devices/e1000/e1000_main-3.10-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.
2585
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
  vim: noexpandtab
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
*******************************************************************************/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include "e1000-3.10-ethercat.h"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <net/ip6_checksum.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/io.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/prefetch.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/bitops.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/if_vlan.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
char e1000_driver_name[] = "ec_e1000";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#define DRV_VERSION "7.3.21-k8-NAPI"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
const char e1000_driver_version[] = DRV_VERSION;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
/* e1000_pci_tbl - PCI Device ID Table
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
 * Last entry must be all 0s
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
 * Macro expands to...
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
	INTEL_E1000_ETHERNET_DEVICE(0x2E6E),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	/* required last entry */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	{0,}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
// do not auto-load driver
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
// MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
int e1000_up(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
void e1000_down(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
void e1000_reinit_locked(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
void e1000_reset(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
                             struct e1000_tx_ring *txdr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
                             struct e1000_rx_ring *rxdr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
                             struct e1000_tx_ring *tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
                             struct e1000_rx_ring *rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
void e1000_update_stats(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_init_module(void);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static void e1000_exit_module(void);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static void e1000_remove(struct pci_dev *pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static int e1000_alloc_queues(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static int e1000_sw_init(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static int e1000_open(struct net_device *netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
static int e1000_close(struct net_device *netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_configure_tx(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
static void e1000_configure_rx(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_setup_rctl(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
                                struct e1000_tx_ring *tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
                                struct e1000_rx_ring *rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static void e1000_set_rx_mode(struct net_device *netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static void e1000_update_phy_info_task(struct work_struct *work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static void e1000_watchdog(struct work_struct *work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
				    struct net_device *netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
static int e1000_set_mac(struct net_device *netdev, void *p);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
void ec_poll(struct net_device *);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
static irqreturn_t e1000_intr(int irq, void *data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
			       struct e1000_tx_ring *tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
static int e1000_clean(struct napi_struct *napi, int budget);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
			       struct e1000_rx_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
			       int *work_done, int work_to_do);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
				     struct e1000_rx_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
				     int *work_done, int work_to_do);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
				   struct e1000_rx_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
				   int cleaned_count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
					 struct e1000_rx_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
					 int cleaned_count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
			   int cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static void e1000_tx_timeout(struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static void e1000_reset_task(struct work_struct *work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
static void e1000_smartspeed(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
                                       struct sk_buff *skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
static bool e1000_vlan_used(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static void e1000_vlan_mode(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
			    netdev_features_t features);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
				     bool filter_on);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
static int e1000_vlan_rx_add_vid(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
				 __be16 proto, u16 vid);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
static int e1000_vlan_rx_kill_vid(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
				  __be16 proto, u16 vid);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
static void e1000_restore_vlan(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
static int e1000_resume(struct pci_dev *pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
static void e1000_shutdown(struct pci_dev *pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
#ifdef CONFIG_NET_POLL_CONTROLLER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
/* for netdump / net console */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
static void e1000_netpoll (struct net_device *netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
#define COPYBREAK_DEFAULT 256
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
module_param(copybreak, uint, 0644);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
MODULE_PARM_DESC(copybreak,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	"Maximum size of packet that is copied to a new buffer on receive");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
                     pci_channel_state_t state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
static void e1000_io_resume(struct pci_dev *pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
static const struct pci_error_handlers e1000_err_handler = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	.error_detected = e1000_io_error_detected,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	.slot_reset = e1000_io_slot_reset,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	.resume = e1000_io_resume,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
static struct pci_driver e1000_driver = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	.name     = e1000_driver_name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	.id_table = e1000_pci_tbl,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	.probe    = e1000_probe,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	.remove   = e1000_remove,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	/* Power Management Hooks */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	.suspend  = e1000_suspend,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	.resume   = e1000_resume,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	.shutdown = e1000_shutdown,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
	.err_handler = &e1000_err_handler
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
MODULE_DESCRIPTION("EtherCAT-capable Intel(R) PRO/1000 Network Driver");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
MODULE_LICENSE("GPL");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
MODULE_VERSION(DRV_VERSION);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
static int debug = -1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
module_param(debug, int, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
 * e1000_get_hw_dev - return device
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
 * used by hardware layer to print debugging information
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
struct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	struct e1000_adapter *adapter = hw->back;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	return adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
 * e1000_init_module - Driver Registration Routine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 * e1000_init_module is the first routine called when the driver is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
 * loaded. All it does is register with the PCI subsystem.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
static int __init e1000_init_module(void)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	int ret;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	pr_info("%s - version %s\n", e1000_driver_string, e1000_driver_version);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	pr_info("%s\n", e1000_copyright);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	ret = pci_register_driver(&e1000_driver);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	if (copybreak != COPYBREAK_DEFAULT) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
		if (copybreak == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
			pr_info("copybreak disabled\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
			pr_info("copybreak enabled for "
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
				   "packets <= %u bytes\n", copybreak);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	return ret;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
module_init(e1000_init_module);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
 * e1000_exit_module - Driver Exit Cleanup Routine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
 * e1000_exit_module is called just before the driver is removed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
 * from memory.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
static void __exit e1000_exit_module(void)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	pci_unregister_driver(&e1000_driver);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
module_exit(e1000_exit_module);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
static int e1000_request_irq(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	irq_handler_t handler = e1000_intr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	int irq_flags = IRQF_SHARED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	                  netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		e_err(probe, "Unable to allocate interrupt Error: %d\n", err);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
static void e1000_free_irq(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	free_irq(adapter->pdev->irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
 * e1000_irq_disable - Mask off interrupt generation on the NIC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
static void e1000_irq_disable(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	ew32(IMC, ~0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	synchronize_irq(adapter->pdev->irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
 * e1000_irq_enable - Enable default interrupt generation settings
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
static void e1000_irq_enable(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	ew32(IMS, IMS_ENABLE_MASK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	u16 vid = hw->mng_cookie.vlan_id;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	u16 old_vid = adapter->mng_vlan_id;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
	if (!e1000_vlan_used(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	if (!test_bit(vid, adapter->active_vlans)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
		if (hw->mng_cookie.status &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
		    E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
			e1000_vlan_rx_add_vid(netdev, htons(ETH_P_8021Q), vid);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
			adapter->mng_vlan_id = vid;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
		if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
		    (vid != old_vid) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
		    !test_bit(old_vid, adapter->active_vlans))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
			e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
					       old_vid);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
		adapter->mng_vlan_id = vid;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
static void e1000_init_manageability(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
	if (adapter->en_mng_pt) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
		u32 manc = er32(MANC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
		/* disable hardware interception of ARP */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		manc &= ~(E1000_MANC_ARP_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
		ew32(MANC, manc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
static void e1000_release_manageability(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	if (adapter->en_mng_pt) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		u32 manc = er32(MANC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
		/* re-enable hardware interception of ARP */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		manc |= E1000_MANC_ARP_EN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		ew32(MANC, manc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
 * e1000_configure - configure the hardware for RX and TX
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
 * @adapter = private board structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
static void e1000_configure(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	e1000_set_rx_mode(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	e1000_restore_vlan(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	e1000_init_manageability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	e1000_configure_tx(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	e1000_setup_rctl(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	e1000_configure_rx(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	/* call E1000_DESC_UNUSED which always leaves
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	 * at least 1 descriptor unused to make sure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	 * next_to_use != next_to_clean
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	for (i = 0; i < adapter->num_rx_queues; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
		if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
			/* fill rx ring completely! */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
			adapter->alloc_rx_buf(adapter, ring, ring->count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
			/* this one leaves the last ring element unallocated! */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
			adapter->alloc_rx_buf(adapter, ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
					E1000_DESC_UNUSED(ring));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
int e1000_up(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	/* hardware has been reset, we need to reload some things */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
	e1000_configure(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	clear_bit(__E1000_DOWN, &adapter->flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
		napi_enable(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
		e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		netif_wake_queue(adapter->netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
		/* fire a link change interrupt to start the watchdog */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
		ew32(ICS, E1000_ICS_LSC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
 * e1000_power_up_phy - restore link in case the phy was powered down
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
 * @adapter: address of board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
 *
26480934a057 Added all drivers for kernel 3.10.
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
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
 * driver is unloaded and wake on lan is not enabled (among others)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
 * *** this routine MUST be followed by a call to e1000_reset ***
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
void e1000_power_up_phy(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	u16 mii_reg = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	/* Just clear the power down bit to wake the phy back up */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	if (hw->media_type == e1000_media_type_copper) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		/* according to the manual, the phy will retain its
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		 * settings across a power-down/up cycle
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		mii_reg &= ~MII_CR_POWER_DOWN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
static void e1000_power_down_phy(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	/* Power down the PHY so no link is implied when interface is down *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	 * The PHY cannot be powered down if any of the following is true *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	 * (a) WoL is enabled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	 * (b) AMT is active
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	 * (c) SoL/IDER session is active
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	   hw->media_type == e1000_media_type_copper) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
		u16 mii_reg = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		switch (hw->mac_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		case e1000_82540:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		case e1000_82545:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		case e1000_82545_rev_3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		case e1000_82546:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
		case e1000_ce4100:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
		case e1000_82546_rev_3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
		case e1000_82541:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		case e1000_82541_rev_2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		case e1000_82547:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		case e1000_82547_rev_2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
				goto out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
			goto out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
		mii_reg |= MII_CR_POWER_DOWN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		msleep(1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
out:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
static void e1000_down_and_stop(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	set_bit(__E1000_DOWN, &adapter->flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	/* Only kill reset task if adapter is not resetting */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	if (!test_bit(__E1000_RESETTING, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		cancel_work_sync(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
		cancel_delayed_work_sync(&adapter->watchdog_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
		cancel_delayed_work_sync(&adapter->phy_info_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
		cancel_delayed_work_sync(&adapter->fifo_stall_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
void e1000_down(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	u32 rctl, tctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	/* disable receives in the hardware */	
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
		/* flush and sleep below */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
		netif_tx_disable(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	/* disable transmits in the hardware */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	tctl = er32(TCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	tctl &= ~E1000_TCTL_EN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	ew32(TCTL, tctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	/* flush both disables and wait for them to finish */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
	msleep(10);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
		napi_disable(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
		e1000_irq_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	/* Setting DOWN must be after irq_disable to prevent
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	 * a screaming interrupt.  Setting DOWN also prevents
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	 * tasks from rescheduling.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	e1000_down_and_stop(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	adapter->link_speed = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	adapter->link_duplex = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		netif_carrier_off(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	e1000_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	e1000_clean_all_tx_rings(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	e1000_clean_all_rx_rings(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
static void e1000_reinit_safe(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		msleep(1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	mutex_lock(&adapter->mutex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	e1000_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	e1000_up(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	mutex_unlock(&adapter->mutex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	clear_bit(__E1000_RESETTING, &adapter->flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
void e1000_reinit_locked(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	/* if rtnl_lock is not held the call path is bogus */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	ASSERT_RTNL();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	WARN_ON(in_interrupt());
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		msleep(1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	e1000_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	e1000_up(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	clear_bit(__E1000_RESETTING, &adapter->flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
void e1000_reset(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	bool legacy_pba_adjust = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	u16 hwm;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	/* Repartition Pba for greater than 9k mtu
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	 * To take effect CTRL.RST is required.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	switch (hw->mac_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	case e1000_82542_rev2_0:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	case e1000_82542_rev2_1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	case e1000_82543:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
	case e1000_82544:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	case e1000_82540:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	case e1000_82541:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	case e1000_82541_rev_2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		legacy_pba_adjust = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		pba = E1000_PBA_48K;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	case e1000_82545:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	case e1000_82545_rev_3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	case e1000_82546:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	case e1000_ce4100:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	case e1000_82546_rev_3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		pba = E1000_PBA_48K;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	case e1000_82547:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	case e1000_82547_rev_2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		legacy_pba_adjust = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
		pba = E1000_PBA_30K;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	case e1000_undefined:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	case e1000_num_macs:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	if (legacy_pba_adjust) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		if (hw->max_frame_size > E1000_RXBUFFER_8192)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
			pba -= 8; /* allocate more FIFO for Tx */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		if (hw->mac_type == e1000_82547) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
			adapter->tx_fifo_head = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
			adapter->tx_fifo_size =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
			atomic_set(&adapter->tx_fifo_stall, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
		/* adjust PBA for jumbo frames */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
		ew32(PBA, pba);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
		/* To maintain wire speed transmits, the Tx FIFO should be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		 * large enough to accommodate two full transmit packets,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
		 * the Rx FIFO should be large enough to accommodate at least
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
		 * one full receive packet and is similarly rounded up and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
		 * expressed in KB.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		pba = er32(PBA);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		/* upper 16 bits has Tx packet buffer allocation size in KB */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
		tx_space = pba >> 16;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		/* lower 16 bits has Rx packet buffer allocation size in KB */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
		pba &= 0xffff;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
		/* the Tx fifo also stores 16 bytes of information about the Tx
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
		 * but don't include ethernet FCS because hardware appends it
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		min_tx_space = (hw->max_frame_size +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
		                sizeof(struct e1000_tx_desc) -
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
		                ETH_FCS_LEN) * 2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
		min_tx_space = ALIGN(min_tx_space, 1024);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
		min_tx_space >>= 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		/* software strips receive CRC, so leave room for it */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
		min_rx_space = hw->max_frame_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
		min_rx_space = ALIGN(min_rx_space, 1024);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
		min_rx_space >>= 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		/* If current Tx allocation is less than the min Tx FIFO size,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		 * and the min Tx FIFO size is less than the current Rx FIFO
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		 * allocation, take space away from current Rx allocation
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
		if (tx_space < min_tx_space &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		    ((min_tx_space - tx_space) < pba)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
			pba = pba - (min_tx_space - tx_space);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
			/* PCI/PCIx hardware has PBA alignment constraints */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
			switch (hw->mac_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
			case e1000_82545 ... e1000_82546_rev_3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
				pba &= ~(E1000_PBA_8K - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
			default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
			/* if short on Rx space, Rx wins and must trump Tx
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
			 * adjustment or use Early Receive if available
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
			if (pba < min_rx_space)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
				pba = min_rx_space;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	ew32(PBA, pba);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	/* flow control settings:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	 * The high water mark must be low enough to fit one full frame
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	 * (or the size used for early receive) above it in the Rx FIFO.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	 * Set it to the lower of:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	 * - 90% of the Rx FIFO size, and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	 * - the full Rx FIFO size minus the early receive size (for parts
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	 * - the full Rx FIFO size minus one full frame
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	hwm = min(((pba << 10) * 9 / 10),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
		  ((pba << 10) - hw->max_frame_size));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	hw->fc_low_water = hw->fc_high_water - 8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	hw->fc_send_xon = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	hw->fc = hw->original_fc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	/* Allow time for pending master requests to run */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	e1000_reset_hw(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	if (hw->mac_type >= e1000_82544)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		ew32(WUC, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	if (e1000_init_hw(hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
		e_dev_err("Hardware Error\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	e1000_update_mng_vlan(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	if (hw->mac_type >= e1000_82544 &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	    hw->autoneg == 1 &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
		u32 ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		/* clear phy power management bit if we are in gig only mode,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		 * which if enabled will attempt negotiation to 100Mb, which
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
		 * can cause a loss of link at power off or driver unload
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
		ctrl &= ~E1000_CTRL_SWDPIN3;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
		ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	e1000_reset_adaptive(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	e1000_phy_get_info(hw, &adapter->phy_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	e1000_release_manageability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
/* Dump the eeprom for users having checksum issues */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	struct ethtool_eeprom eeprom;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	const struct ethtool_ops *ops = netdev->ethtool_ops;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	u8 *data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	u16 csum_old, csum_new = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	eeprom.len = ops->get_eeprom_len(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	eeprom.offset = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	data = kmalloc(eeprom.len, GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	if (!data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	ops->get_eeprom(netdev, &eeprom, data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		csum_new += data[i] + (data[i + 1] << 8);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	csum_new = EEPROM_SUM - csum_new;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	pr_err("/*********************/\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	pr_err("Current EEPROM Checksum : 0x%04x\n", csum_old);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	pr_err("Calculated              : 0x%04x\n", csum_new);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	pr_err("Offset    Values\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	pr_err("========  ======\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	pr_err("Include this output when contacting your support provider.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	pr_err("This is not a software error! Something bad happened to\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	pr_err("your hardware or EEPROM image. Ignoring this problem could\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	pr_err("result in further problems, possibly loss of data,\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	pr_err("corruption or system hangs!\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	pr_err("The MAC Address will be reset to 00:00:00:00:00:00,\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
	pr_err("which is invalid and requires you to set the proper MAC\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	pr_err("address manually before continuing to enable this network\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	pr_err("device. Please inspect the EEPROM dump and report the\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	pr_err("issue to your hardware vendor or Intel Customer Support.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	pr_err("/*********************/\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	kfree(data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
 * @pdev: PCI device information struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
 * Return true if an adapter needs ioport resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
static int e1000_is_need_ioport(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	switch (pdev->device) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	case E1000_DEV_ID_82540EM:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	case E1000_DEV_ID_82540EM_LOM:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	case E1000_DEV_ID_82540EP:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	case E1000_DEV_ID_82540EP_LOM:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	case E1000_DEV_ID_82540EP_LP:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	case E1000_DEV_ID_82541EI:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	case E1000_DEV_ID_82541EI_MOBILE:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	case E1000_DEV_ID_82541ER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	case E1000_DEV_ID_82541ER_LOM:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	case E1000_DEV_ID_82541GI:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	case E1000_DEV_ID_82541GI_LF:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	case E1000_DEV_ID_82541GI_MOBILE:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	case E1000_DEV_ID_82544EI_COPPER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	case E1000_DEV_ID_82544EI_FIBER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	case E1000_DEV_ID_82544GC_COPPER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	case E1000_DEV_ID_82544GC_LOM:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	case E1000_DEV_ID_82545EM_COPPER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	case E1000_DEV_ID_82545EM_FIBER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	case E1000_DEV_ID_82546EB_COPPER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	case E1000_DEV_ID_82546EB_FIBER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
		return true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		return false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
static netdev_features_t e1000_fix_features(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	netdev_features_t features)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	/* Since there is no support for separate Rx/Tx vlan accel
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	 * enable/disable make sure Tx flag is always in same state as Rx.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	if (features & NETIF_F_HW_VLAN_CTAG_RX)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
		features |= NETIF_F_HW_VLAN_CTAG_TX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
		features &= ~NETIF_F_HW_VLAN_CTAG_TX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	return features;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
static int e1000_set_features(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	netdev_features_t features)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	netdev_features_t changed = features ^ netdev->features;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
		e1000_vlan_mode(netdev, features);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	if (!(changed & (NETIF_F_RXCSUM | NETIF_F_RXALL)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	netdev->features = features;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
		e1000_reinit_locked(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		e1000_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
static const struct net_device_ops e1000_netdev_ops = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	.ndo_open		= e1000_open,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	.ndo_stop		= e1000_close,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	.ndo_start_xmit		= e1000_xmit_frame,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	.ndo_get_stats		= e1000_get_stats,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	.ndo_set_rx_mode	= e1000_set_rx_mode,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	.ndo_set_mac_address	= e1000_set_mac,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	.ndo_tx_timeout		= e1000_tx_timeout,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	.ndo_change_mtu		= e1000_change_mtu,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	.ndo_do_ioctl		= e1000_ioctl,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	.ndo_validate_addr	= eth_validate_addr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
#ifdef CONFIG_NET_POLL_CONTROLLER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	.ndo_poll_controller	= e1000_netpoll,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	.ndo_fix_features	= e1000_fix_features,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	.ndo_set_features	= e1000_set_features,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
 * e1000_init_hw_struct - initialize members of hw struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
 * @adapter: board private struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
 * @hw: structure used by e1000_hw.c
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
 * Factors out initialization of the e1000_hw struct to its own function
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
 * that can be called very early at init (just after struct allocation).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
 * Fields are initialized based on PCI device information and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
 * OS network device settings (MTU size).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
 * Returns negative error codes if MAC type setup fails.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
static int e1000_init_hw_struct(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
				struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	/* PCI config space info */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	hw->vendor_id = pdev->vendor;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	hw->device_id = pdev->device;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	hw->subsystem_id = pdev->subsystem_device;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	hw->revision_id = pdev->revision;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	hw->max_frame_size = adapter->netdev->mtu +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	/* identify the MAC */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	if (e1000_set_mac_type(hw)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		e_err(probe, "Unknown MAC Type\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		return -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	switch (hw->mac_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	case e1000_82541:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	case e1000_82547:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	case e1000_82541_rev_2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	case e1000_82547_rev_2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		hw->phy_init_script = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	e1000_set_media_type(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	e1000_get_bus_info(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	hw->wait_autoneg_complete = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	hw->tbi_compatibility_en = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	hw->adaptive_ifs = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	/* Copper options */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	if (hw->media_type == e1000_media_type_copper) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
		hw->mdix = AUTO_ALL_MODES;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
		hw->disable_polarity_correction = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
		hw->master_slave = E1000_MASTER_SLAVE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
 * e1000_probe - Device Initialization Routine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
 * @pdev: PCI device information struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
 * @ent: entry in e1000_pci_tbl
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
 * Returns 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
 * e1000_probe initializes an adapter identified by a pci_dev structure.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
 * The OS initialization, configuring of the adapter private structure,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
 * and a hardware reset occur.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	struct net_device *netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	struct e1000_adapter *adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	struct e1000_hw *hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	static int cards_found = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	int i, err, pci_using_dac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	u16 eeprom_data = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	u16 tmp = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	int bars, need_ioport;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	/* do not allocate ioport bars when not needed */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	need_ioport = e1000_is_need_ioport(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	if (need_ioport) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		err = pci_enable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		err = pci_enable_device_mem(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		goto err_pci_reg;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	pci_set_master(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	err = pci_save_state(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		goto err_alloc_etherdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	err = -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	if (!netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		goto err_alloc_etherdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	SET_NETDEV_DEV(netdev, &pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	pci_set_drvdata(pdev, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	adapter->netdev = netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	adapter->pdev = pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	adapter->bars = bars;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	adapter->need_ioport = need_ioport;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	hw->back = adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
	err = -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	if (!hw->hw_addr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		goto err_ioremap;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	if (adapter->need_ioport) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		for (i = BAR_1; i <= BAR_5; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
			if (pci_resource_len(pdev, i) == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
				continue;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
				hw->io_base = pci_resource_start(pdev, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	/* make ready for any if (hw->...) below */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	err = e1000_init_hw_struct(adapter, hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		goto err_sw_init;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	/* there is a workaround being applied below that limits
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	 * 64-bit DMA addresses to 64-bit hardware.  There are some
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	 * 32-bit adapters that Tx hang when given 64-bit DMA addresses
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	pci_using_dac = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	if ((hw->bus_type == e1000_bus_type_pcix) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	    !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		/* according to DMA-API-HOWTO, coherent calls will always
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		 * succeed if the set call did
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		pci_using_dac = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
		if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
			pr_err("No usable DMA config, aborting\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
			goto err_dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	netdev->netdev_ops = &e1000_netdev_ops;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	e1000_set_ethtool_ops(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	netdev->watchdog_timeo = 5 * HZ;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	adapter->bd_number = cards_found;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	/* setup the private structure */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	err = e1000_sw_init(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
		goto err_sw_init;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	err = -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	if (hw->mac_type == e1000_ce4100) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		hw->ce4100_gbe_mdio_base_virt =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
					ioremap(pci_resource_start(pdev, BAR_1),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		                                pci_resource_len(pdev, BAR_1));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		if (!hw->ce4100_gbe_mdio_base_virt)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
			goto err_mdio_ioremap;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	if (hw->mac_type >= e1000_82543) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		netdev->hw_features = NETIF_F_SG |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
				   NETIF_F_HW_CSUM |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
				   NETIF_F_HW_VLAN_CTAG_RX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		netdev->features = NETIF_F_HW_VLAN_CTAG_TX |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
				   NETIF_F_HW_VLAN_CTAG_FILTER;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	if ((hw->mac_type >= e1000_82544) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	   (hw->mac_type != e1000_82547))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		netdev->hw_features |= NETIF_F_TSO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	netdev->priv_flags |= IFF_SUPP_NOFCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	netdev->features |= netdev->hw_features;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	netdev->hw_features |= (NETIF_F_RXCSUM |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
				NETIF_F_RXALL |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
				NETIF_F_RXFCS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	if (pci_using_dac) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
		netdev->features |= NETIF_F_HIGHDMA;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
		netdev->vlan_features |= NETIF_F_HIGHDMA;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	netdev->vlan_features |= (NETIF_F_TSO |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
				  NETIF_F_HW_CSUM |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
				  NETIF_F_SG);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	netdev->priv_flags |= IFF_UNICAST_FLT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
	/* initialize eeprom parameters */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	if (e1000_init_eeprom_params(hw)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		e_err(probe, "EEPROM initialization failed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		goto err_eeprom;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	/* before reading the EEPROM, reset the controller to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
	 * put the device in a known good starting state
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
	e1000_reset_hw(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	/* make sure the EEPROM is good */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	if (e1000_validate_eeprom_checksum(hw) < 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		e_err(probe, "The EEPROM Checksum Is Not Valid\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		e1000_dump_eeprom(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		/* set MAC address to all zeroes to invalidate and temporary
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		 * disable this device for the user. This blocks regular
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		 * traffic while still permitting ethtool ioctls from reaching
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		 * the hardware as well as allowing the user to run the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		 * interface after manually setting a hw addr using
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		 * `ip set address`
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		memset(hw->mac_addr, 0, netdev->addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		/* copy the MAC address out of the EEPROM */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
		if (e1000_read_mac_addr(hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
			e_err(probe, "EEPROM Read Error\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	/* don't block initalization here due to bad MAC address */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	if (!is_valid_ether_addr(netdev->dev_addr))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		e_err(probe, "Invalid MAC Address\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	INIT_DELAYED_WORK(&adapter->watchdog_task, e1000_watchdog);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	INIT_DELAYED_WORK(&adapter->fifo_stall_task,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
			  e1000_82547_tx_fifo_stall_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	INIT_DELAYED_WORK(&adapter->phy_info_task, e1000_update_phy_info_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	e1000_check_options(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	/* Initial Wake on LAN setting
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	 * If APM wake is enabled in the EEPROM,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	 * enable the ACPI Magic Packet filter
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	switch (hw->mac_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	case e1000_82542_rev2_0:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	case e1000_82542_rev2_1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	case e1000_82543:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	case e1000_82544:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		e1000_read_eeprom(hw,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	case e1000_82546:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	case e1000_82546_rev_3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
			e1000_read_eeprom(hw,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		/* Fall Through */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		e1000_read_eeprom(hw,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	if (eeprom_data & eeprom_apme_mask)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		adapter->eeprom_wol |= E1000_WUFC_MAG;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	/* now that we have the eeprom settings, apply the special cases
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	 * where the eeprom may be wrong or the board simply won't support
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	 * wake on lan on a particular port
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	switch (pdev->device) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	case E1000_DEV_ID_82546GB_PCIE:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		adapter->eeprom_wol = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	case E1000_DEV_ID_82546EB_FIBER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	case E1000_DEV_ID_82546GB_FIBER:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		/* Wake events only supported on port A for dual fiber
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		 * regardless of eeprom setting
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
			adapter->eeprom_wol = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		/* if quad port adapter, disable WoL on all but port A */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		if (global_quad_port_a != 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
			adapter->eeprom_wol = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
			adapter->quad_port_a = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		/* Reset for multiple quad port adapters */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		if (++global_quad_port_a == 4)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
			global_quad_port_a = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
	/* initialize the wol settings based on the eeprom settings */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
	adapter->wol = adapter->eeprom_wol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	/* Auto detect PHY address */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	if (hw->mac_type == e1000_ce4100) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
		for (i = 0; i < 32; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
			hw->phy_addr = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
			e1000_read_phy_reg(hw, PHY_ID2, &tmp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
			if (tmp == 0 || tmp == 0xFF) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
				if (i == 31)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
					goto err_eeprom;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
				continue;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
			} else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	/* reset the hardware with the new settings */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	e1000_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
 	// offer device to EtherCAT master module
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
		err = ecdev_open(adapter->ecdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
		if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
			ecdev_withdraw(adapter->ecdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
			goto err_register;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
		strcpy(netdev->name, "eth%d");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
		err = register_netdev(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
		if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
			goto err_register;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
	e1000_vlan_filter_on_off(adapter, false);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	/* print bus type/speed/width info */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	       netdev->dev_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
		/* carrier off reporting is important to ethtool even BEFORE open */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
		netif_carrier_off(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	e_info(probe, "Intel(R) PRO/1000 Network Connection\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	cards_found++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
err_register:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
err_eeprom:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
	e1000_phy_hw_reset(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	if (hw->flash_address)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		iounmap(hw->flash_address);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	kfree(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	kfree(adapter->rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
err_dma:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
err_sw_init:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
err_mdio_ioremap:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	iounmap(hw->ce4100_gbe_mdio_base_virt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	iounmap(hw->hw_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
err_ioremap:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	free_netdev(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
err_alloc_etherdev:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	pci_release_selected_regions(pdev, bars);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
err_pci_reg:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
	pci_disable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
 * e1000_remove - Device Removal Routine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
 * @pdev: PCI device information struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
 * e1000_remove is called by the PCI subsystem to alert the driver
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
 * that it should release a PCI device.  The could be caused by a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
 * Hot-Plug event, or because the driver is going to be removed from
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
 * memory.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
static void e1000_remove(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	e1000_down_and_stop(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	e1000_release_manageability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		ecdev_close(adapter->ecdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
		ecdev_withdraw(adapter->ecdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
		unregister_netdev(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
	e1000_phy_hw_reset(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
	kfree(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	kfree(adapter->rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	if (hw->mac_type == e1000_ce4100)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
		iounmap(hw->ce4100_gbe_mdio_base_virt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	iounmap(hw->hw_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	if (hw->flash_address)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		iounmap(hw->flash_address);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	pci_release_selected_regions(pdev, adapter->bars);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	free_netdev(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	pci_disable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
 * @adapter: board private structure to initialize
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
 * e1000_sw_init initializes the Adapter private data structure.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
 * e1000_init_hw_struct MUST be called before this function
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
static int e1000_sw_init(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	adapter->num_tx_queues = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	adapter->num_rx_queues = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	if (e1000_alloc_queues(adapter)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
		e_err(probe, "Unable to allocate memory for queues\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	/* Explicitly disable IRQ since the NIC can be in any state. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	e1000_irq_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	spin_lock_init(&adapter->stats_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	mutex_init(&adapter->mutex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	set_bit(__E1000_DOWN, &adapter->flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
 * e1000_alloc_queues - Allocate memory for all rings
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
 * @adapter: board private structure to initialize
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
 * We allocate one ring per queue at run-time since we don't know the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
 * number of queues at compile-time.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
static int e1000_alloc_queues(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
	if (!adapter->tx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	if (!adapter->rx_ring) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
		kfree(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	return E1000_SUCCESS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
 * e1000_open - Called when a network interface is made active
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
 * Returns 0 on success, negative value on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
 * The open entry point is called when a network interface is made
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
 * active by the system (IFF_UP).  At this point all resources needed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
 * for transmit and receive operations are allocated, the interrupt
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
 * handler is registered with the OS, the watchdog task is started,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
 * and the stack is notified that the interface is ready.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
static int e1000_open(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	/* disallow open during test */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
	if (test_bit(__E1000_TESTING, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
		return -EBUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	netif_carrier_off(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
	/* allocate transmit descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	err = e1000_setup_all_tx_resources(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
		goto err_setup_tx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	/* allocate receive descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	err = e1000_setup_all_rx_resources(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		goto err_setup_rx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
	e1000_power_up_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	if ((hw->mng_cookie.status &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
		e1000_update_mng_vlan(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
	/* before we allocate an interrupt, we must be ready to handle it.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	 * as soon as we call pci_request_irq, so we have to setup our
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	 * clean_rx handler before we do so.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
	e1000_configure(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	err = e1000_request_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
		goto err_req_irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	/* From here on the code is the same as e1000_up() */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
	clear_bit(__E1000_DOWN, &adapter->flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
		napi_enable(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		netif_start_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	/* fire a link status change interrupt to start the watchdog */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	ew32(ICS, E1000_ICS_LSC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
	return E1000_SUCCESS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
err_req_irq:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	e1000_power_down_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	e1000_free_all_rx_resources(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
err_setup_rx:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	e1000_free_all_tx_resources(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
err_setup_tx:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	e1000_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
 * e1000_close - Disables a network interface
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
 * Returns 0, this is not allowed to fail
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
 * The close entry point is called when an interface is de-activated
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
 * by the OS.  The hardware is still under the drivers control, but
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
 * needs to be disabled.  A global MAC reset is issued to stop the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
 * hardware, and all transmit and receive resources are freed.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
static int e1000_close(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
	e1000_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	e1000_power_down_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	e1000_free_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	e1000_free_all_tx_resources(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	e1000_free_all_rx_resources(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	/* kill manageability vlan ID if supported, but not if a vlan with
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	 * the same ID is registered on the host OS (let 8021q kill it)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	if ((hw->mng_cookie.status &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
	    !test_bit(adapter->mng_vlan_id, adapter->active_vlans)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
		e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
				       adapter->mng_vlan_id);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
 * @adapter: address of board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
 * @start: address of beginning of memory
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
 * @len: length of memory
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
				  unsigned long len)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	unsigned long begin = (unsigned long)start;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	unsigned long end = begin + len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	/* First rev 82545 and 82546 need to not allow any memory
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	 * write location to cross 64k boundary due to errata 23
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	if (hw->mac_type == e1000_82545 ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	    hw->mac_type == e1000_ce4100 ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	    hw->mac_type == e1000_82546) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	return true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
 * @txdr:    tx descriptor ring (for a specific queue) to setup
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
 * Return 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
				    struct e1000_tx_ring *txdr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	int size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
	size = sizeof(struct e1000_buffer) * txdr->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	txdr->buffer_info = vzalloc(size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	if (!txdr->buffer_info)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	/* round up to nearest 4K */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	txdr->size = ALIGN(txdr->size, 4096);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
					GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	if (!txdr->desc) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
setup_tx_desc_die:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
		vfree(txdr->buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	/* Fix for errata 23, can't cross 64kB boundary */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
		void *olddesc = txdr->desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
		dma_addr_t olddma = txdr->dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
		e_err(tx_err, "txdr align check failed: %u bytes at %p\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
		      txdr->size, txdr->desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
		/* Try again, without freeing the previous */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
		txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
						&txdr->dma, GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
		/* Failed allocation, critical failure */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
		if (!txdr->desc) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
					  olddma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
			goto setup_tx_desc_die;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
			/* give up */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
			dma_free_coherent(&pdev->dev, txdr->size, txdr->desc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
					  txdr->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
					  olddma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
			e_err(probe, "Unable to allocate aligned memory "
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
			      "for the transmit descriptor ring\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
			vfree(txdr->buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
			return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
			/* Free old allocation, new allocation was successful */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
					  olddma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	memset(txdr->desc, 0, txdr->size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	txdr->next_to_use = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	txdr->next_to_clean = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
 * 				  (Descriptors) for all queues
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
 * Return 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	int i, err = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	for (i = 0; i < adapter->num_tx_queues; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
			e_err(probe, "Allocation for Tx Queue %u failed\n", i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
			for (i-- ; i >= 0; i--)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
				e1000_free_tx_resources(adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
							&adapter->tx_ring[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
 * Configure the Tx unit of the MAC after a reset.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
static void e1000_configure_tx(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	u64 tdba;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	u32 tdlen, tctl, tipg;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
	u32 ipgr1, ipgr2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	/* Setup the HW Tx Head and Tail descriptor pointers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
	switch (adapter->num_tx_queues) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	case 1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
		tdba = adapter->tx_ring[0].dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
		tdlen = adapter->tx_ring[0].count *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
			sizeof(struct e1000_tx_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		ew32(TDLEN, tdlen);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		ew32(TDBAH, (tdba >> 32));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		ew32(TDT, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
		ew32(TDH, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
					   E1000_TDH : E1000_82542_TDH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
					   E1000_TDT : E1000_82542_TDT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	/* Set the default values for the Tx Inter Packet Gap timer */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	if ((hw->media_type == e1000_media_type_fiber ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	     hw->media_type == e1000_media_type_internal_serdes))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	switch (hw->mac_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	case e1000_82542_rev2_0:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	case e1000_82542_rev2_1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
		tipg = DEFAULT_82542_TIPG_IPGT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	ew32(TIPG, tipg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	/* Set the Tx Interrupt Delay register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	ew32(TIDV, adapter->tx_int_delay);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	if (hw->mac_type >= e1000_82540)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		ew32(TADV, adapter->tx_abs_int_delay);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	/* Program the Transmit Control Register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	tctl = er32(TCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	tctl &= ~E1000_TCTL_CT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	e1000_config_collision_dist(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	/* Setup Transmit Descriptor Settings for eop descriptor */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	/* only set IDE if we are delaying interrupts using the timers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	if (adapter->tx_int_delay)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	if (hw->mac_type < e1000_82543)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	/* Cache if we're 82544 running in PCI-X because we'll
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	 * need this to apply a workaround later in the send path.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	if (hw->mac_type == e1000_82544 &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	    hw->bus_type == e1000_bus_type_pcix)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		adapter->pcix_82544 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	ew32(TCTL, tctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
 * Returns 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
				    struct e1000_rx_ring *rxdr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	int size, desc_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	size = sizeof(struct e1000_buffer) * rxdr->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	rxdr->buffer_info = vzalloc(size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	if (!rxdr->buffer_info)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	desc_len = sizeof(struct e1000_rx_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	/* Round up to nearest 4K */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	rxdr->size = rxdr->count * desc_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	rxdr->size = ALIGN(rxdr->size, 4096);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
					GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	if (!rxdr->desc) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
setup_rx_desc_die:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		vfree(rxdr->buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	/* Fix for errata 23, can't cross 64kB boundary */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		void *olddesc = rxdr->desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		dma_addr_t olddma = rxdr->dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		e_err(rx_err, "rxdr align check failed: %u bytes at %p\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		      rxdr->size, rxdr->desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		/* Try again, without freeing the previous */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
						&rxdr->dma, GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
		/* Failed allocation, critical failure */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		if (!rxdr->desc) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
					  olddma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
			goto setup_rx_desc_die;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
			/* give up */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
			dma_free_coherent(&pdev->dev, rxdr->size, rxdr->desc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
					  rxdr->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
					  olddma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
			e_err(probe, "Unable to allocate aligned memory for "
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
			      "the Rx descriptor ring\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
			goto setup_rx_desc_die;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
			/* Free old allocation, new allocation was successful */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
					  olddma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	memset(rxdr->desc, 0, rxdr->size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	rxdr->next_to_clean = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	rxdr->next_to_use = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	rxdr->rx_skb_top = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
 * 				  (Descriptors) for all queues
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
 * Return 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	int i, err = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	for (i = 0; i < adapter->num_rx_queues; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
		if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
			e_err(probe, "Allocation for Rx Queue %u failed\n", i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
			for (i-- ; i >= 0; i--)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
				e1000_free_rx_resources(adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
							&adapter->rx_ring[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
 * e1000_setup_rctl - configure the receive control registers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
 * @adapter: Board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
static void e1000_setup_rctl(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
	u32 rctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	rctl |= E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
		E1000_RCTL_RDMTS_HALF |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	if (hw->tbi_compatibility_on == 1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
		rctl |= E1000_RCTL_SBP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
		rctl &= ~E1000_RCTL_SBP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
		rctl &= ~E1000_RCTL_LPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		rctl |= E1000_RCTL_LPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	/* Setup buffer sizes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	rctl &= ~E1000_RCTL_SZ_4096;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	rctl |= E1000_RCTL_BSEX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	switch (adapter->rx_buffer_len) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		case E1000_RXBUFFER_2048:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
		default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
			rctl |= E1000_RCTL_SZ_2048;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
			rctl &= ~E1000_RCTL_BSEX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
		case E1000_RXBUFFER_4096:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
			rctl |= E1000_RCTL_SZ_4096;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		case E1000_RXBUFFER_8192:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
			rctl |= E1000_RCTL_SZ_8192;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		case E1000_RXBUFFER_16384:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
			rctl |= E1000_RCTL_SZ_16384;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
	/* This is useful for sniffing bad packets. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
	if (adapter->netdev->features & NETIF_F_RXALL) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		/* UPE and MPE will be handled by normal PROMISC logic
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
		 * in e1000e_set_rx_mode
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
			 E1000_RCTL_BAM | /* RX All Bcast Pkts */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
			 E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
		rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
			  E1000_RCTL_DPF | /* Allow filtered pause */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
			  E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
		 * and that breaks VLANs.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
 * Configure the Rx unit of the MAC after a reset.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
static void e1000_configure_rx(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	u64 rdba;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	u32 rdlen, rctl, rxcsum;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
		rdlen = adapter->rx_ring[0].count *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
		        sizeof(struct e1000_rx_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
		rdlen = adapter->rx_ring[0].count *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
		        sizeof(struct e1000_rx_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
		adapter->clean_rx = e1000_clean_rx_irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	/* disable receives while setting up the descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	/* set the Receive Delay Timer Register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
	ew32(RDTR, adapter->rx_int_delay);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	if (hw->mac_type >= e1000_82540) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
		ew32(RADV, adapter->rx_abs_int_delay);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
		if (adapter->itr_setting != 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
			ew32(ITR, 1000000000 / (adapter->itr * 256));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
	 * the Base and Length of the Rx Descriptor Ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	switch (adapter->num_rx_queues) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	case 1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		rdba = adapter->rx_ring[0].dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
		ew32(RDLEN, rdlen);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
		ew32(RDBAH, (rdba >> 32));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
		ew32(RDT, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
		ew32(RDH, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
					   E1000_RDH : E1000_82542_RDH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
					   E1000_RDT : E1000_82542_RDT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	if (hw->mac_type >= e1000_82543) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
		rxcsum = er32(RXCSUM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
		if (adapter->rx_csum)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
			rxcsum |= E1000_RXCSUM_TUOFL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
			/* don't need to clear IPPCSE as it defaults to 0 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
			rxcsum &= ~E1000_RXCSUM_TUOFL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		ew32(RXCSUM, rxcsum);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
	/* Enable Receives */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
	ew32(RCTL, rctl | E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
 * e1000_free_tx_resources - Free Tx Resources per Queue
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
 * @tx_ring: Tx descriptor ring for a specific queue
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
 * Free all transmit software resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
				    struct e1000_tx_ring *tx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	e1000_clean_tx_ring(adapter, tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	vfree(tx_ring->buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	tx_ring->buffer_info = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
			  tx_ring->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	tx_ring->desc = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
 * Free all transmit software resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	for (i = 0; i < adapter->num_tx_queues; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
					     struct e1000_buffer *buffer_info)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
	if (buffer_info->dma) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		if (buffer_info->mapped_as_page)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
				       buffer_info->length, DMA_TO_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
					 buffer_info->length,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
					 DMA_TO_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
		buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	if (buffer_info->skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
		dev_kfree_skb_any(buffer_info->skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
		buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	buffer_info->time_stamp = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	/* buffer_info must be completely set up in the transmit path */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
 * e1000_clean_tx_ring - Free Tx Buffers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
 * @tx_ring: ring to be cleaned
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
				struct e1000_tx_ring *tx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
	unsigned long size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
	/* Free all the Tx ring sk_buffs */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	for (i = 0; i < tx_ring->count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
	netdev_reset_queue(adapter->netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	size = sizeof(struct e1000_buffer) * tx_ring->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
	memset(tx_ring->buffer_info, 0, size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	/* Zero out the descriptor ring */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	memset(tx_ring->desc, 0, tx_ring->size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	tx_ring->next_to_use = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	tx_ring->next_to_clean = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	tx_ring->last_tx_tso = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	writel(0, hw->hw_addr + tx_ring->tdh);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	writel(0, hw->hw_addr + tx_ring->tdt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	for (i = 0; i < adapter->num_tx_queues; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
 * e1000_free_rx_resources - Free Rx Resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
 * @rx_ring: ring to clean the resources from
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
 * Free all receive software resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
				    struct e1000_rx_ring *rx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	e1000_clean_rx_ring(adapter, rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	vfree(rx_ring->buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	rx_ring->buffer_info = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
			  rx_ring->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	rx_ring->desc = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
 * Free all receive software resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	for (i = 0; i < adapter->num_rx_queues; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
 * @rx_ring: ring to free buffers from
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
				struct e1000_rx_ring *rx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	unsigned long size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	/* Free all the Rx ring sk_buffs */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	for (i = 0; i < rx_ring->count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
		buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
		if (buffer_info->dma &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
		    adapter->clean_rx == e1000_clean_rx_irq) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
			dma_unmap_single(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
			                 buffer_info->length,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
					 DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		} else if (buffer_info->dma &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
			dma_unmap_page(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
				       buffer_info->length,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
				       DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
		buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
		if (buffer_info->page) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
			put_page(buffer_info->page);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
			buffer_info->page = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
		if (buffer_info->skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			dev_kfree_skb(buffer_info->skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	/* there also may be some cached data from a chained receive */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	if (rx_ring->rx_skb_top) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
		dev_kfree_skb(rx_ring->rx_skb_top);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
		rx_ring->rx_skb_top = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	size = sizeof(struct e1000_buffer) * rx_ring->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	memset(rx_ring->buffer_info, 0, size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
	/* Zero out the descriptor ring */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	memset(rx_ring->desc, 0, rx_ring->size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
	rx_ring->next_to_clean = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	rx_ring->next_to_use = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
	writel(0, hw->hw_addr + rx_ring->rdh);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
	writel(0, hw->hw_addr + rx_ring->rdt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	for (i = 0; i < adapter->num_rx_queues; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
 * and memory write and invalidate disabled for certain operations
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	u32 rctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	e1000_pci_clear_mwi(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
	rctl |= E1000_RCTL_RST;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	mdelay(5);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	if (!adapter->ecdev && netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
		e1000_clean_all_rx_rings(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	u32 rctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	rctl &= ~E1000_RCTL_RST;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	mdelay(5);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
		e1000_pci_set_mwi(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
	if (!adapter->netdev && netif_running(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
		/* No need to loop, because 82542 supports only 1 queue */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
		e1000_configure_rx(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
		if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
			/* fill rx ring completely! */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
			adapter->alloc_rx_buf(adapter, ring, ring->count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
			/* this one leaves the last ring element unallocated! */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
			adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
 * e1000_set_mac - Change the Ethernet Address of the NIC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
 * @p: pointer to an address structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
 * Returns 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
static int e1000_set_mac(struct net_device *netdev, void *p)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	struct sockaddr *addr = p;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	if (!is_valid_ether_addr(addr->sa_data))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
		return -EADDRNOTAVAIL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	/* 82542 2.0 needs to be in reset to write receive address registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	if (hw->mac_type == e1000_82542_rev2_0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
		e1000_enter_82542_rst(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	e1000_rar_set(hw, hw->mac_addr, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
	if (hw->mac_type == e1000_82542_rev2_0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
		e1000_leave_82542_rst(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
 * The set_rx_mode entry point is called whenever the unicast or multicast
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
 * address lists or the network interface flags are updated. This routine is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
 * responsible for configuring the hardware for proper unicast, multicast,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
 * promiscuous mode, and all-multi behavior.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
static void e1000_set_rx_mode(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	struct netdev_hw_addr *ha;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	bool use_uc = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	u32 rctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	u32 hash_value;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	int i, rar_entries = E1000_RAR_ENTRIES;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	if (!mcarray)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
	/* Check for Promiscuous and All Multicast modes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	if (netdev->flags & IFF_PROMISC) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
		rctl &= ~E1000_RCTL_VFE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
		if (netdev->flags & IFF_ALLMULTI)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
			rctl |= E1000_RCTL_MPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
			rctl &= ~E1000_RCTL_MPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
		/* Enable VLAN filter if there is a VLAN */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		if (e1000_vlan_used(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
			rctl |= E1000_RCTL_VFE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	if (netdev_uc_count(netdev) > rar_entries - 1) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
		rctl |= E1000_RCTL_UPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	} else if (!(netdev->flags & IFF_PROMISC)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
		rctl &= ~E1000_RCTL_UPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
		use_uc = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	/* 82542 2.0 needs to be in reset to write receive address registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	if (hw->mac_type == e1000_82542_rev2_0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		e1000_enter_82542_rst(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
	/* load the first 14 addresses into the exact filters 1-14. Unicast
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
	 * addresses take precedence to avoid disabling unicast filtering
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	 * when possible.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
	 * RAR 0 is used for the station MAC address
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	 * if there are not 14 addresses, go ahead and clear the filters
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
	i = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	if (use_uc)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
		netdev_for_each_uc_addr(ha, netdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
			if (i == rar_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
			e1000_rar_set(hw, ha->addr, i++);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
	netdev_for_each_mc_addr(ha, netdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		if (i == rar_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
			/* load any remaining addresses into the hash table */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
			u32 hash_reg, hash_bit, mta;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
			hash_value = e1000_hash_mc_addr(hw, ha->addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
			hash_reg = (hash_value >> 5) & 0x7F;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
			hash_bit = hash_value & 0x1F;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
			mta = (1 << hash_bit);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
			mcarray[hash_reg] |= mta;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
			e1000_rar_set(hw, ha->addr, i++);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	for (; i < rar_entries; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
		E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
		E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
	/* write the hash table completely, write from bottom to avoid
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
	 * both stupid write combining chipsets, and flushing each write
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	for (i = mta_reg_count - 1; i >= 0 ; i--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
		/* If we are on an 82544 has an errata where writing odd
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
		 * offsets overwrites the previous even offset, but writing
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
		 * backwards over the range solves the issue by always
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
		 * writing the odd offset first
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
	E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
	if (hw->mac_type == e1000_82542_rev2_0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
		e1000_leave_82542_rst(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	kfree(mcarray);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
 * e1000_update_phy_info_task - get phy info
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
 * @work: work struct contained inside adapter struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
 * Need to wait a few seconds after link up to get diagnostic information from
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
 * the phy
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
static void e1000_update_phy_info_task(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	struct e1000_adapter *adapter = container_of(work,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
						     struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
						     phy_info_task.work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	if (test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	mutex_lock(&adapter->mutex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
	mutex_unlock(&adapter->mutex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
 * e1000_82547_tx_fifo_stall_task - task to complete work
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
 * @work: work struct contained inside adapter struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
	struct e1000_adapter *adapter = container_of(work,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
						     struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
						     fifo_stall_task.work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
	u32 tctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	if (test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	mutex_lock(&adapter->mutex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
	if (atomic_read(&adapter->tx_fifo_stall)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
		if ((er32(TDT) == er32(TDH)) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
		   (er32(TDFT) == er32(TDFH)) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
		   (er32(TDFTS) == er32(TDFHS))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
			tctl = er32(TCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
			ew32(TDFT, adapter->tx_head_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
			ew32(TDFH, adapter->tx_head_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
			ew32(TDFTS, adapter->tx_head_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
			ew32(TDFHS, adapter->tx_head_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
			ew32(TCTL, tctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
			E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
			adapter->tx_fifo_head = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
			atomic_set(&adapter->tx_fifo_stall, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
			netif_wake_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
			schedule_delayed_work(&adapter->fifo_stall_task, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	mutex_unlock(&adapter->mutex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
bool e1000_has_link(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	bool link_active = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	/* get_link_status is set on LSC (link status) interrupt or rx
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	 * sequence error interrupt (except on intel ce4100).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
	 * get_link_status will stay false until the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	 * e1000_check_for_link establishes link for copper adapters
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
	 * ONLY
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
	switch (hw->media_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
	case e1000_media_type_copper:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		if (hw->mac_type == e1000_ce4100)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
			hw->get_link_status = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
		if (hw->get_link_status) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
			e1000_check_for_link(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
			link_active = !hw->get_link_status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
			link_active = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	case e1000_media_type_fiber:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
		e1000_check_for_link(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	case e1000_media_type_internal_serdes:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
		e1000_check_for_link(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
		link_active = hw->serdes_has_link;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
	return link_active;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
 * e1000_watchdog - work function
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
 * @work: work struct contained inside adapter struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
static void e1000_watchdog(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	struct e1000_adapter *adapter = container_of(work,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
						     struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
						     watchdog_task.work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
	struct e1000_tx_ring *txdr = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	u32 link, tctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	if (test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	mutex_lock(&adapter->mutex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
	link = e1000_has_link(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
	if (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		goto link_up;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
	if (link) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
		if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
				|| (!adapter->ecdev && !netif_carrier_ok(netdev))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
			u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
			bool txb2b __attribute__ ((unused)) = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
			/* update snapshot of PHY registers on LSC */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
			e1000_get_speed_and_duplex(hw,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
						   &adapter->link_speed,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
						   &adapter->link_duplex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
			ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
			pr_info("%s NIC Link is Up %d Mbps %s, "
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
				"Flow Control: %s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
				netdev->name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
				adapter->link_speed,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
				adapter->link_duplex == FULL_DUPLEX ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
				"Full Duplex" : "Half Duplex",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
				((ctrl & E1000_CTRL_TFCE) && (ctrl &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
				E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
				E1000_CTRL_RFCE) ? "RX" : ((ctrl &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
				E1000_CTRL_TFCE) ? "TX" : "None")));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
			/* adjust timeout factor according to speed/duplex */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
			adapter->tx_timeout_factor = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
			switch (adapter->link_speed) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
			case SPEED_10:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
				txb2b = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
				adapter->tx_timeout_factor = 16;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			case SPEED_100:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
				txb2b = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
				/* maybe add some timeout factor ? */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
			/* enable transmits in the hardware */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
			tctl = er32(TCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
			tctl |= E1000_TCTL_EN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
			ew32(TCTL, tctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
			if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
				ecdev_set_link(adapter->ecdev, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
			else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
				netif_carrier_on(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
				if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
					schedule_delayed_work(&adapter->phy_info_task,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
							2 * HZ);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
			adapter->smartspeed = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
		if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
				|| (!adapter->ecdev && netif_carrier_ok(netdev))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
			adapter->link_speed = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
			adapter->link_duplex = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
			pr_info("%s NIC Link is Down\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
				netdev->name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
			if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
				ecdev_set_link(adapter->ecdev, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
				netif_carrier_off(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
				if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
					schedule_delayed_work(&adapter->phy_info_task,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
							2 * HZ);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
		e1000_smartspeed(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
link_up:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
	e1000_update_stats(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	adapter->tpt_old = adapter->stats.tpt;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
	adapter->colc_old = adapter->stats.colc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	adapter->gorcl_old = adapter->stats.gorcl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
	adapter->gotcl_old = adapter->stats.gotcl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
	e1000_update_adaptive(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
	if (!adapter->ecdev && !netif_carrier_ok(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
			/* We've lost link, so the controller stops DMA,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
			 * but we've got queued Tx work that's never going
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
			 * to get done, so reset controller to flush Tx.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
			 * (Do the reset outside of interrupt context).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
			adapter->tx_timeout_count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
			schedule_work(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
			/* exit immediately since reset is imminent */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
			goto unlock;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
	/* Simple mode for Interrupt Throttle Rate (ITR) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
		/* Symmetric Tx/Rx gets a reduced ITR=2000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
		 * Total asymmetrical Tx or Rx gets ITR=8000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
		 * everyone else is between 2000-8000.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
		u32 dif = (adapter->gotcl > adapter->gorcl ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
			    adapter->gotcl - adapter->gorcl :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
			    adapter->gorcl - adapter->gotcl) / 10000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
		ew32(ITR, 1000000000 / (itr * 256));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	/* Cause software interrupt to ensure rx ring is cleaned */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	ew32(ICS, E1000_ICS_RXDMT0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	/* Force detection of hung controller every watchdog period */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	adapter->detect_tx_hung = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
	/* Reschedule the task */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
		schedule_delayed_work(&adapter->watchdog_task, 2 * HZ);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
unlock:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	mutex_unlock(&adapter->mutex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
enum latency_range {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	lowest_latency = 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
	low_latency = 1,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	bulk_latency = 2,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	latency_invalid = 255
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
 * e1000_update_itr - update the dynamic ITR value based on statistics
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
 * @adapter: pointer to adapter
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
 * @itr_setting: current adapter->itr
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
 * @packets: the number of packets during this measurement interval
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
 * @bytes: the number of bytes during this measurement interval
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
 *      Stores a new ITR value based on packets and byte
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
 *      counts during the last interrupt.  The advantage of per interrupt
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
 *      computation is faster updates and more accurate ITR for the current
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
 *      traffic pattern.  Constants in this function were computed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
 *      based on theoretical maximum wire speed and thresholds were set based
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
 *      on testing data as well as attempting to minimize response time
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
 *      while increasing bulk throughput.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
 *      this functionality is controlled by the InterruptThrottleRate module
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
 *      parameter (see e1000_param.c)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
				     u16 itr_setting, int packets, int bytes)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	unsigned int retval = itr_setting;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	if (unlikely(hw->mac_type < e1000_82540))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
		goto update_itr_done;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	if (packets == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
		goto update_itr_done;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	switch (itr_setting) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	case lowest_latency:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
		/* jumbo frames get bulk treatment*/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
		if (bytes/packets > 8000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
			retval = bulk_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		else if ((packets < 5) && (bytes > 512))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
			retval = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
	case low_latency:  /* 50 usec aka 20000 ints/s */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
		if (bytes > 10000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
			/* jumbo frames need bulk latency setting */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
			if (bytes/packets > 8000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
				retval = bulk_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
			else if ((packets < 10) || ((bytes/packets) > 1200))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
				retval = bulk_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
			else if ((packets > 35))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
				retval = lowest_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
		} else if (bytes/packets > 2000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
			retval = bulk_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		else if (packets <= 2 && bytes < 512)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
			retval = lowest_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	case bulk_latency: /* 250 usec aka 4000 ints/s */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		if (bytes > 25000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
			if (packets > 35)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
				retval = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
		} else if (bytes < 6000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
			retval = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
update_itr_done:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
static void e1000_set_itr(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
	u16 current_itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
	u32 new_itr = adapter->itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
	if (unlikely(hw->mac_type < e1000_82540))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
	if (unlikely(adapter->link_speed != SPEED_1000)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		current_itr = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
		new_itr = 4000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
		goto set_itr_now;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	adapter->tx_itr = e1000_update_itr(adapter, adapter->tx_itr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
					   adapter->total_tx_packets,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
					   adapter->total_tx_bytes);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
		adapter->tx_itr = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	adapter->rx_itr = e1000_update_itr(adapter, adapter->rx_itr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
					   adapter->total_rx_packets,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
					   adapter->total_rx_bytes);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
		adapter->rx_itr = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	switch (current_itr) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	/* counts and packets in update_itr are dependent on these numbers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	case lowest_latency:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		new_itr = 70000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
	case low_latency:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
		new_itr = 20000; /* aka hwitr = ~200 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	case bulk_latency:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
		new_itr = 4000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
set_itr_now:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
	if (new_itr != adapter->itr) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
		/* this attempts to bias the interrupt rate towards Bulk
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
		 * by adding intermediate steps when interrupt rate is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
		 * increasing
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
		new_itr = new_itr > adapter->itr ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
			  min(adapter->itr + (new_itr >> 2), new_itr) :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
			  new_itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
		adapter->itr = new_itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		ew32(ITR, 1000000000 / (new_itr * 256));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
#define E1000_TX_FLAGS_CSUM		0x00000001
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
#define E1000_TX_FLAGS_VLAN		0x00000002
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
#define E1000_TX_FLAGS_TSO		0x00000004
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
#define E1000_TX_FLAGS_IPV4		0x00000008
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
#define E1000_TX_FLAGS_NO_FCS		0x00000010
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
#define E1000_TX_FLAGS_VLAN_SHIFT	16
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
static int e1000_tso(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
	struct e1000_context_desc *context_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
	u32 cmd_length = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	u16 ipcse = 0, tucse, mss;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	if (skb_is_gso(skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		if (skb_header_cloned(skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
			if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
				return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
		mss = skb_shinfo(skb)->gso_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
		if (skb->protocol == htons(ETH_P_IP)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
			struct iphdr *iph = ip_hdr(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
			iph->tot_len = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
			iph->check = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
								 iph->daddr, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
								 IPPROTO_TCP,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
								 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
			cmd_length = E1000_TXD_CMD_IP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
			ipcse = skb_transport_offset(skb) - 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
			ipv6_hdr(skb)->payload_len = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
			tcp_hdr(skb)->check =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
						 &ipv6_hdr(skb)->daddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
						 0, IPPROTO_TCP, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
			ipcse = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
		ipcss = skb_network_offset(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
		tucss = skb_transport_offset(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
		tucse = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
		i = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
		context_desc->upper_setup.tcp_fields.tucss = tucss;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
		context_desc->upper_setup.tcp_fields.tucso = tucso;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
		buffer_info->time_stamp = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
		buffer_info->next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
		if (++i == tx_ring->count) i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
		tx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
		return true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	return false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
static bool e1000_tx_csum(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
	struct e1000_context_desc *context_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
	u8 css;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
	u32 cmd_len = E1000_TXD_CMD_DEXT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	if (skb->ip_summed != CHECKSUM_PARTIAL)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
		return false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	switch (skb->protocol) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	case cpu_to_be16(ETH_P_IP):
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
			cmd_len |= E1000_TXD_CMD_TCP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
	case cpu_to_be16(ETH_P_IPV6):
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
		/* XXX not handling all IPV6 headers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
			cmd_len |= E1000_TXD_CMD_TCP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
		if (unlikely(net_ratelimit()))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
			e_warn(drv, "checksum_partial proto=%x!\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
			       skb->protocol);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	css = skb_checksum_start_offset(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	i = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	context_desc->lower_setup.ip_config = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	context_desc->upper_setup.tcp_fields.tucss = css;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	context_desc->upper_setup.tcp_fields.tucso =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
		css + skb->csum_offset;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	context_desc->upper_setup.tcp_fields.tucse = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
	context_desc->tcp_seg_setup.data = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
	buffer_info->time_stamp = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
	buffer_info->next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	if (unlikely(++i == tx_ring->count)) i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	tx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	return true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
#define E1000_MAX_TXD_PWR	12
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
static int e1000_tx_map(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
			struct e1000_tx_ring *tx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
			struct sk_buff *skb, unsigned int first,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
			unsigned int max_per_txd, unsigned int nr_frags,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
			unsigned int mss)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	unsigned int len = skb_headlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	unsigned int offset = 0, size, count = 0, i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	unsigned int f, bytecount, segs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	i = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	while (len) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		size = min(len, max_per_txd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		/* Workaround for Controller erratum --
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		 * descriptor for non-tso packet in a linear SKB that follows a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		 * tso gets written back prematurely before the data is fully
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		 * DMA'd to the controller
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		if (!skb->data_len && tx_ring->last_tx_tso &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		    !skb_is_gso(skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
			tx_ring->last_tx_tso = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
			size -= 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		/* Workaround for premature desc write-backs
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		 * in TSO mode.  Append 4-byte sentinel desc
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		if (unlikely(mss && !nr_frags && size == len && size > 8))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
			size -= 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		/* work-around for errata 10 and it applies
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		 * to all controllers in PCI-X mode
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		 * The fix is to make sure that the first descriptor of a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
		                (size > 2015) && count == 0))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
		        size = 2015;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		 * terminating buffers within evenly-aligned dwords.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		if (unlikely(adapter->pcix_82544 &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
		   size > 4))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
			size -= 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
		buffer_info->length = size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
		/* set time_stamp *before* dma to help avoid a possible race */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
		buffer_info->time_stamp = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
		buffer_info->mapped_as_page = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
		buffer_info->dma = dma_map_single(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
						  skb->data + offset,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
						  size, DMA_TO_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
			goto dma_error;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		buffer_info->next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
		len -= size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
		offset += size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
		if (len) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
			i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
			if (unlikely(i == tx_ring->count))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
				i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
	for (f = 0; f < nr_frags; f++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
		const struct skb_frag_struct *frag;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
		frag = &skb_shinfo(skb)->frags[f];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		len = skb_frag_size(frag);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		offset = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
		while (len) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
			unsigned long bufend;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
			i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
			if (unlikely(i == tx_ring->count))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
				i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
			buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
			size = min(len, max_per_txd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
			/* Workaround for premature desc write-backs
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
			 * in TSO mode.  Append 4-byte sentinel desc
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
			if (unlikely(mss && f == (nr_frags-1) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
			    size == len && size > 8))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
				size -= 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
			/* Workaround for potential 82544 hang in PCI-X.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
			 * Avoid terminating buffers within evenly-aligned
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
			 * dwords.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
			bufend = (unsigned long)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
				page_to_phys(skb_frag_page(frag));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
			bufend += offset + size - 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
			if (unlikely(adapter->pcix_82544 &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
				     !(bufend & 4) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
				     size > 4))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
				size -= 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
			buffer_info->length = size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
			buffer_info->time_stamp = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
			buffer_info->mapped_as_page = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
			buffer_info->dma = skb_frag_dma_map(&pdev->dev, frag,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
						offset, size, DMA_TO_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
				goto dma_error;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
			buffer_info->next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
			len -= size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
			offset += size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
			count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
	segs = skb_shinfo(skb)->gso_segs ?: 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	/* multiply data chunks by size of headers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	tx_ring->buffer_info[i].skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	tx_ring->buffer_info[i].segs = segs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
	tx_ring->buffer_info[i].bytecount = bytecount;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
	tx_ring->buffer_info[first].next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	return count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
dma_error:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	dev_err(&pdev->dev, "TX DMA map failed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	if (count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		count--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	while (count--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		if (i==0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
			i += tx_ring->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
		i--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
static void e1000_tx_queue(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
			   struct e1000_tx_ring *tx_ring, int tx_flags,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
			   int count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
	struct e1000_tx_desc *tx_desc = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
			     E1000_TXD_CMD_TSE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
		txd_lower |= E1000_TXD_CMD_VLE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
		txd_lower &= ~(E1000_TXD_CMD_IFCS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
	i = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
	while (count--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		tx_desc = E1000_TX_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
		tx_desc->lower.data =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
			cpu_to_le32(txd_lower | buffer_info->length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		tx_desc->upper.data = cpu_to_le32(txd_upper);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		if (unlikely(++i == tx_ring->count)) i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	/* txd_cmd re-enables FCS, so we'll re-disable it here as desired. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
		tx_desc->lower.data &= ~(cpu_to_le32(E1000_TXD_CMD_IFCS));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	/* Force memory writes to complete before letting h/w
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	 * know there are new descriptors to fetch.  (Only
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
	 * applicable for weak-ordered memory model archs,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	 * such as IA-64).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
	tx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	writel(i, hw->hw_addr + tx_ring->tdt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
	/* we need this if more than one processor can write to our tail
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
	 * at a time, it synchronizes IO on IA64/Altix systems
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
	mmiowb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
/* 82547 workaround to avoid controller hang in half-duplex environment.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
 * The workaround is to avoid queuing a large packet that would span
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
 * the internal Tx FIFO ring boundary by notifying the stack to resend
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
 * to the beginning of the Tx FIFO.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
#define E1000_FIFO_HDR			0x10
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
#define E1000_82547_PAD_LEN		0x3E0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
				       struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	if (adapter->link_duplex != HALF_DUPLEX)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
		goto no_fifo_stall_required;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	if (atomic_read(&adapter->tx_fifo_stall))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
		return 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
		atomic_set(&adapter->tx_fifo_stall, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		return 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
no_fifo_stall_required:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	adapter->tx_fifo_head += skb_fifo_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		return -EBUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
	netif_stop_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	/* Herbert's original patch had:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
	 *  smp_mb__after_netif_stop_queue();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
	 * but since that doesn't exist yet, just open code it.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
	smp_mb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	/* We need to check again in a case another CPU has just
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
	 * made room available.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
		return -EBUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	/* A reprieve! */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
	netif_start_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
	++adapter->restart_queue;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
static int e1000_maybe_stop_tx(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
			       struct e1000_tx_ring *tx_ring, int size)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	return __e1000_maybe_stop_tx(netdev, size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
				    struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	struct e1000_tx_ring *tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	unsigned int tx_flags = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	unsigned int len = skb_headlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	unsigned int nr_frags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	unsigned int mss;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	int count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	int tso;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	unsigned int f;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	/* This goes back to the question of how to logically map a Tx queue
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	 * to a flow.  Right now, performance is impacted slightly negatively
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	 * if using multiple Tx queues.  If the stack breaks away from a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	 * single qdisc implementation, we can look at this again.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	if (unlikely(skb->len <= 0)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
		if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
			dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
		return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	/* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	 * packets may get corrupted during padding by HW.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
	 * To WA this issue, pad all small packets manually.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	if (skb->len < ETH_ZLEN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
		if (skb_pad(skb, ETH_ZLEN - skb->len))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
			return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
		skb->len = ETH_ZLEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
		skb_set_tail_pointer(skb, ETH_ZLEN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	mss = skb_shinfo(skb)->gso_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	/* The controller does a simple calculation to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	 * make sure there is enough room in the FIFO before
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	 * initiating the DMA for each buffer.  The calc is:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	 * 4 = ceil(buffer len/mss).  To make sure we don't
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	 * overrun the FIFO, adjust the max buffer len if mss
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	 * drops.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	if (mss) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
		u8 hdr_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
		max_per_txd = min(mss << 2, max_per_txd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
		max_txd_pwr = fls(max_per_txd) - 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
		if (skb->data_len && hdr_len == len) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
			switch (hw->mac_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
				unsigned int pull_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
			case e1000_82544:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
				/* Make sure we have room to chop off 4 bytes,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
				 * and that the end alignment will work out to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
				 * this hardware's requirements
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
				 * NOTE: this is a TSO only workaround
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
				 * if end byte alignment not correct move us
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
				 * into the next dword
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
				 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
				if ((unsigned long)(skb_tail_pointer(skb) - 1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
				    & 4)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
					break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
				/* fall through */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
				pull_size = min((unsigned int)4, skb->data_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
				if (!__pskb_pull_tail(skb, pull_size)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
					e_err(drv, "__pskb_pull_tail "
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
					      "failed.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
					if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
						dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
					}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
					return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
				len = skb_headlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
			default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
				/* do nothing */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	/* reserve a descriptor for the offload context */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
		count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
	count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	/* Controller Erratum workaround */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
		count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	count += TXD_USE_COUNT(len, max_txd_pwr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	if (adapter->pcix_82544)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
		count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	/* work-around for errata 10 and it applies to all controllers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	 * in PCI-X mode, so add one more descriptor to the count
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
			(len > 2015)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
		count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	nr_frags = skb_shinfo(skb)->nr_frags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	for (f = 0; f < nr_frags; f++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
		count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
				       max_txd_pwr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	if (adapter->pcix_82544)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
		count += nr_frags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	/* need: count + 2 desc gap to keep tail from touching
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	 * head, otherwise try next time
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		return NETDEV_TX_BUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	if (unlikely((hw->mac_type == e1000_82547) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
		     (e1000_82547_fifo_workaround(adapter, skb)))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
		if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
			netif_stop_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
			if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
				schedule_delayed_work(&adapter->fifo_stall_task, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
		return NETDEV_TX_BUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	if (vlan_tx_tag_present(skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
		tx_flags |= E1000_TX_FLAGS_VLAN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	first = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	tso = e1000_tso(adapter, tx_ring, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	if (tso < 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
		if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
			dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
		return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	if (likely(tso)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
		if (likely(hw->mac_type != e1000_82544))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
			tx_ring->last_tx_tso = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
		tx_flags |= E1000_TX_FLAGS_TSO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		tx_flags |= E1000_TX_FLAGS_CSUM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
	if (likely(skb->protocol == htons(ETH_P_IP)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
		tx_flags |= E1000_TX_FLAGS_IPV4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	if (unlikely(skb->no_fcs))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
		tx_flags |= E1000_TX_FLAGS_NO_FCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
			     nr_frags, mss);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	if (count) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
		netdev_sent_queue(netdev, skb->len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
		skb_tx_timestamp(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
		if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
			/* Make sure there is space in the ring for the next send. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
			e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
		if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
			dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
		tx_ring->buffer_info[first].time_stamp = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
		tx_ring->next_to_use = first;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
	return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
#define NUM_REGS 38 /* 1 based count */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
static void e1000_regdump(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	u32 regs[NUM_REGS];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	u32 *regs_buff = regs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	int i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	static const char * const reg_name[] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
		"CTRL",  "STATUS",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
		"RCTL", "RDLEN", "RDH", "RDT", "RDTR",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
		"TCTL", "TDBAL", "TDBAH", "TDLEN", "TDH", "TDT",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
		"TIDV", "TXDCTL", "TADV", "TARC0",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
		"TDBAL1", "TDBAH1", "TDLEN1", "TDH1", "TDT1",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		"TXDCTL1", "TARC1",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		"CTRL_EXT", "ERT", "RDBAL", "RDBAH",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
		"TDFH", "TDFT", "TDFHS", "TDFTS", "TDFPC",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
		"RDFH", "RDFT", "RDFHS", "RDFTS", "RDFPC"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
	regs_buff[0]  = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
	regs_buff[1]  = er32(STATUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	regs_buff[2]  = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
	regs_buff[3]  = er32(RDLEN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	regs_buff[4]  = er32(RDH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	regs_buff[5]  = er32(RDT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
	regs_buff[6]  = er32(RDTR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	regs_buff[7]  = er32(TCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	regs_buff[8]  = er32(TDBAL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	regs_buff[9]  = er32(TDBAH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	regs_buff[10] = er32(TDLEN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	regs_buff[11] = er32(TDH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
	regs_buff[12] = er32(TDT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	regs_buff[13] = er32(TIDV);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
	regs_buff[14] = er32(TXDCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	regs_buff[15] = er32(TADV);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
	regs_buff[16] = er32(TARC0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
	regs_buff[17] = er32(TDBAL1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	regs_buff[18] = er32(TDBAH1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
	regs_buff[19] = er32(TDLEN1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	regs_buff[20] = er32(TDH1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
	regs_buff[21] = er32(TDT1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	regs_buff[22] = er32(TXDCTL1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
	regs_buff[23] = er32(TARC1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
	regs_buff[24] = er32(CTRL_EXT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	regs_buff[25] = er32(ERT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
	regs_buff[26] = er32(RDBAL0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	regs_buff[27] = er32(RDBAH0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
	regs_buff[28] = er32(TDFH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
	regs_buff[29] = er32(TDFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
	regs_buff[30] = er32(TDFHS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
	regs_buff[31] = er32(TDFTS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
	regs_buff[32] = er32(TDFPC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	regs_buff[33] = er32(RDFH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	regs_buff[34] = er32(RDFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	regs_buff[35] = er32(RDFHS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	regs_buff[36] = er32(RDFTS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	regs_buff[37] = er32(RDFPC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	pr_info("Register dump\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	for (i = 0; i < NUM_REGS; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
		pr_info("%-15s  %08x\n", reg_name[i], regs_buff[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
/*
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
 * e1000_dump: Print registers, tx ring and rx ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
static void e1000_dump(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	/* this code doesn't handle multiple rings */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	struct e1000_rx_ring *rx_ring = adapter->rx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
	if (!netif_msg_hw(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
	/* Print Registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	e1000_regdump(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	/* transmit dump */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	pr_info("TX Desc ring0 dump\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	 * Legacy Transmit Descriptor
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
	 *   +--------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
	 *   +--------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
	 *   +--------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	 *   63       48 47        36 35    32 31     24 23    16 15        0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	 *   63      48 47    40 39       32 31             16 15    8 7      0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	 * Extended Data Descriptor (DTYP=0x1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
	 * 0 |                     Buffer Address [63:0]                      |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	pr_info("Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma       ] leng  ntw timestmp         bi->skb\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	pr_info("Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen] [bi->dma       ] leng  ntw timestmp         bi->skb\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
	if (!netif_msg_tx_done(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
		goto rx_ring_summary;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
		struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
		struct my_u { __le64 a; __le64 b; };
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
		struct my_u *u = (struct my_u *)tx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
		const char *type;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
			type = "NTC/U";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
		else if (i == tx_ring->next_to_use)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
			type = "NTU";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
		else if (i == tx_ring->next_to_clean)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
			type = "NTC";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
			type = "";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
		pr_info("T%c[0x%03X]    %016llX %016llX %016llX %04X  %3X %016llX %p %s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
			((le64_to_cpu(u->b) & (1<<20)) ? 'd' : 'c'), i,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
			le64_to_cpu(u->a), le64_to_cpu(u->b),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
			(u64)buffer_info->dma, buffer_info->length,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
			buffer_info->next_to_watch,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
			(u64)buffer_info->time_stamp, buffer_info->skb, type);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
rx_ring_summary:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	/* receive dump */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
	pr_info("\nRX Desc ring dump\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	/* Legacy Receive Descriptor Format
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	 * +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	 * |                Buffer Address [63:0]                |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
	 * +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	 * | VLAN Tag | Errors | Status 0 | Packet csum | Length |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
	 * +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
	 * 63       48 47    40 39      32 31         16 15      0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
	pr_info("R[desc]      [address 63:0  ] [vl er S cks ln] [bi->dma       ] [bi->skb]\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
	if (!netif_msg_rx_status(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
		goto exit;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
	for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
		struct e1000_buffer *buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
		struct my_u { __le64 a; __le64 b; };
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
		struct my_u *u = (struct my_u *)rx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
		const char *type;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
		if (i == rx_ring->next_to_use)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
			type = "NTU";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
		else if (i == rx_ring->next_to_clean)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
			type = "NTC";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
			type = "";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		pr_info("R[0x%03X]     %016llX %016llX %016llX %p %s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
			i, le64_to_cpu(u->a), le64_to_cpu(u->b),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
			(u64)buffer_info->dma, buffer_info->skb, type);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
	} /* for */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
	/* dump the descriptor caches */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
	/* rx */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
	pr_info("Rx descriptor cache in 64bit format\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
	for (i = 0x6000; i <= 0x63FF ; i += 0x10) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
		pr_info("R%04X: %08X|%08X %08X|%08X\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
			i,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
			readl(adapter->hw.hw_addr + i+4),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
			readl(adapter->hw.hw_addr + i),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
			readl(adapter->hw.hw_addr + i+12),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
			readl(adapter->hw.hw_addr + i+8));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	/* tx */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
	pr_info("Tx descriptor cache in 64bit format\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
	for (i = 0x7000; i <= 0x73FF ; i += 0x10) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		pr_info("T%04X: %08X|%08X %08X|%08X\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
			i,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
			readl(adapter->hw.hw_addr + i+4),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
			readl(adapter->hw.hw_addr + i),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
			readl(adapter->hw.hw_addr + i+12),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
			readl(adapter->hw.hw_addr + i+8));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
exit:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
 * e1000_tx_timeout - Respond to a Tx Hang
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
static void e1000_tx_timeout(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	/* Do the reset outside of interrupt context */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
	adapter->tx_timeout_count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
	schedule_work(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
static void e1000_reset_task(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	struct e1000_adapter *adapter =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
		container_of(work, struct e1000_adapter, reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	if (test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	e_err(drv, "Reset adapter\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	e1000_reinit_safe(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
 * e1000_get_stats - Get System Network Statistics
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
 * Returns the address of the device statistics structure.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
 * The statistics are actually updated from the watchdog.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	/* only return the current stats */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
	return &netdev->stats;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
 * e1000_change_mtu - Change the Maximum Transfer Unit
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
 * @new_mtu: new value for maximum frame size
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
 * Returns 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
		return -EBUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
		e_err(probe, "Invalid MTU setting\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
		return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	/* Adapter-specific max frame size limits. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	switch (hw->mac_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	case e1000_undefined ... e1000_82542_rev2_1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
			e_err(probe, "Jumbo Frames not supported.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
			return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		msleep(1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
	/* e1000_down has a dependency on max_frame_size */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
	hw->max_frame_size = max_frame;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
		e1000_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
	 * means we reserve 2 more, this pushes us to allocate from the next
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
	 * larger slab size.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
	 * i.e. RXBUFFER_2048 --> size-4096 slab
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
	 * however with the new *_jumbo_rx* routines, jumbo receives will use
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
	 * fragmented skbs
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
	if (max_frame <= E1000_RXBUFFER_2048)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
		adapter->rx_buffer_len = PAGE_SIZE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
	/* adjust allocation if LPE protects us, and we aren't using SBP */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
	if (!hw->tbi_compatibility_on &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
	pr_info("%s changing MTU from %d to %d\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
		netdev->name, netdev->mtu, new_mtu);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
	netdev->mtu = new_mtu;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
		e1000_up(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
		e1000_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	clear_bit(__E1000_RESETTING, &adapter->flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
 * e1000_update_stats - Update the board statistics counters
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
void e1000_update_stats(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
	unsigned long flags = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
	u16 phy_tmp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
	/* Prevent stats update while adapter is being reset, or if the pci
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
	 * connection is down.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
	if (adapter->link_speed == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
	if (pci_channel_offline(pdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
		spin_lock_irqsave(&adapter->stats_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	/* these counters are modified from e1000_tbi_adjust_stats,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
	 * called from the interrupt context, so they must only
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
	 * be written while holding adapter->stats_lock
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
	adapter->stats.crcerrs += er32(CRCERRS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
	adapter->stats.gprc += er32(GPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	adapter->stats.gorcl += er32(GORCL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	adapter->stats.gorch += er32(GORCH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
	adapter->stats.bprc += er32(BPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	adapter->stats.mprc += er32(MPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
	adapter->stats.roc += er32(ROC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
	adapter->stats.prc64 += er32(PRC64);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
	adapter->stats.prc127 += er32(PRC127);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
	adapter->stats.prc255 += er32(PRC255);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
	adapter->stats.prc511 += er32(PRC511);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
	adapter->stats.prc1023 += er32(PRC1023);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
	adapter->stats.prc1522 += er32(PRC1522);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
	adapter->stats.symerrs += er32(SYMERRS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	adapter->stats.mpc += er32(MPC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
	adapter->stats.scc += er32(SCC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	adapter->stats.ecol += er32(ECOL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
	adapter->stats.mcc += er32(MCC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	adapter->stats.latecol += er32(LATECOL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
	adapter->stats.dc += er32(DC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
	adapter->stats.sec += er32(SEC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
	adapter->stats.rlec += er32(RLEC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
	adapter->stats.xonrxc += er32(XONRXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
	adapter->stats.xontxc += er32(XONTXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
	adapter->stats.xoffrxc += er32(XOFFRXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
	adapter->stats.xofftxc += er32(XOFFTXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
	adapter->stats.fcruc += er32(FCRUC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
	adapter->stats.gptc += er32(GPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
	adapter->stats.gotcl += er32(GOTCL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
	adapter->stats.gotch += er32(GOTCH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
	adapter->stats.rnbc += er32(RNBC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
	adapter->stats.ruc += er32(RUC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
	adapter->stats.rfc += er32(RFC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
	adapter->stats.rjc += er32(RJC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
	adapter->stats.torl += er32(TORL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
	adapter->stats.torh += er32(TORH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
	adapter->stats.totl += er32(TOTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
	adapter->stats.toth += er32(TOTH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
	adapter->stats.tpr += er32(TPR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	adapter->stats.ptc64 += er32(PTC64);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
	adapter->stats.ptc127 += er32(PTC127);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	adapter->stats.ptc255 += er32(PTC255);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	adapter->stats.ptc511 += er32(PTC511);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
	adapter->stats.ptc1023 += er32(PTC1023);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	adapter->stats.ptc1522 += er32(PTC1522);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
	adapter->stats.mptc += er32(MPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	adapter->stats.bptc += er32(BPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
	/* used for adaptive IFS */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	hw->tx_packet_delta = er32(TPT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	adapter->stats.tpt += hw->tx_packet_delta;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	hw->collision_delta = er32(COLC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	adapter->stats.colc += hw->collision_delta;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
	if (hw->mac_type >= e1000_82543) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
		adapter->stats.algnerrc += er32(ALGNERRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
		adapter->stats.rxerrc += er32(RXERRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
		adapter->stats.tncrs += er32(TNCRS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
		adapter->stats.cexterr += er32(CEXTERR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
		adapter->stats.tsctc += er32(TSCTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		adapter->stats.tsctfc += er32(TSCTFC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
	/* Fill out the OS statistics structure */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	netdev->stats.multicast = adapter->stats.mprc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
	netdev->stats.collisions = adapter->stats.colc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	/* Rx Errors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
	/* RLEC on some newer hardware can be incorrect so build
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
	 * our own version based on RUC and ROC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
	netdev->stats.rx_errors = adapter->stats.rxerrc +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
		adapter->stats.crcerrs + adapter->stats.algnerrc +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
		adapter->stats.ruc + adapter->stats.roc +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		adapter->stats.cexterr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
	/* Tx Errors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	netdev->stats.tx_errors = adapter->stats.txerrc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	netdev->stats.tx_window_errors = adapter->stats.latecol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
	if (hw->bad_tx_carr_stats_fd &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
	    adapter->link_duplex == FULL_DUPLEX) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
		netdev->stats.tx_carrier_errors = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
		adapter->stats.tncrs = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
	/* Tx Dropped needs to be maintained elsewhere */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
	/* Phy Stats */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
	if (hw->media_type == e1000_media_type_copper) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
		if ((adapter->link_speed == SPEED_1000) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
			adapter->phy_stats.idle_errors += phy_tmp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
		if ((hw->mac_type <= e1000_82546) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
		   (hw->phy_type == e1000_phy_m88) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
			adapter->phy_stats.receive_errors += phy_tmp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
	/* Management Stats */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
	if (hw->has_smbus) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
		adapter->stats.mgptc += er32(MGTPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		adapter->stats.mgprc += er32(MGTPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
		adapter->stats.mgpdc += er32(MGTPDC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
void ec_poll(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
	if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
		e1000_watchdog(&adapter->watchdog_task.work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
		adapter->ec_watchdog_jiffies = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	e1000_intr(0, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
 * e1000_intr - Interrupt Handler
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
 * @irq: interrupt number
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
 * @data: pointer to a network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
static irqreturn_t e1000_intr(int irq, void *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	struct net_device *netdev = data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
	u32 icr = er32(ICR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
	if (unlikely((!icr)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
		return IRQ_NONE;  /* Not our interrupt */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
	/* we might have caused the interrupt, but the above
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
	 * read cleared it, and just in case the driver is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
	 * down there is nothing to do so return handled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
	if (unlikely(test_bit(__E1000_DOWN, &adapter->flags)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
		return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
		hw->get_link_status = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
		/* guard against interrupt when we're going down */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
		if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
			schedule_delayed_work(&adapter->watchdog_task, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
		int i, ec_work_done = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
		for (i = 0; i < E1000_MAX_INTR; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
							&ec_work_done, 100) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
						!e1000_clean_tx_irq(adapter, adapter->tx_ring))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
 	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		/* disable interrupts, without the synchronize_irq bit */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
		ew32(IMC, ~0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		E1000_WRITE_FLUSH();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		if (likely(napi_schedule_prep(&adapter->napi))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
			adapter->total_tx_bytes = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
			adapter->total_tx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
			adapter->total_rx_bytes = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
			adapter->total_rx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
			__napi_schedule(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
			/* this really should not happen! if it does it is basically a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
			 * bug, but not a hard error, so enable ints and continue
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
			if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
				e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
	return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
 * e1000_clean - NAPI Rx polling callback
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
 * EtherCAT: never called
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
static int e1000_clean(struct napi_struct *napi, int budget)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
						     napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
	int tx_clean_complete = 0, work_done = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
	if (!tx_clean_complete)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
		work_done = budget;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
	/* If budget not fully consumed, exit the polling mode */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	if (work_done < budget) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
		if (likely(adapter->itr_setting & 3))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
			e1000_set_itr(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
		napi_complete(napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
		if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
			e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
	return work_done;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
			       struct e1000_tx_ring *tx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
	struct e1000_tx_desc *tx_desc, *eop_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
	unsigned int i, eop;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
	unsigned int count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
	unsigned int total_tx_bytes=0, total_tx_packets=0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
	unsigned int bytes_compl = 0, pkts_compl = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	i = tx_ring->next_to_clean;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
	eop = tx_ring->buffer_info[i].next_to_watch;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
	       (count < tx_ring->count)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
		bool cleaned = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
		rmb();	/* read buffer_info after eop_desc */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
		for ( ; !cleaned; count++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
			tx_desc = E1000_TX_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
			buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
			cleaned = (i == eop);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
			if (cleaned) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
				total_tx_packets += buffer_info->segs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
				total_tx_bytes += buffer_info->bytecount;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
				if (buffer_info->skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
					bytes_compl += buffer_info->skb->len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
					pkts_compl++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
			tx_desc->upper.data = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
			if (unlikely(++i == tx_ring->count)) i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
		eop = tx_ring->buffer_info[i].next_to_watch;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
	tx_ring->next_to_clean = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
2599
4b0b906df1b4 Fixed bug concerning netdev_completed_queue(); thanks to B. Benner.
Florian Pose <fp@igh-essen.com>
parents: 2585
diff changeset
  4007
	if (!adapter->ecdev) {
4b0b906df1b4 Fixed bug concerning netdev_completed_queue(); thanks to B. Benner.
Florian Pose <fp@igh-essen.com>
parents: 2585
diff changeset
  4008
		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: 2585
diff changeset
  4009
	}
2585
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
#define TX_WAKE_THRESHOLD 32
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
	if (!adapter->ecdev && unlikely(count && netif_carrier_ok(netdev) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
		/* Make sure that anybody stopping the queue after this
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
		 * sees the new next_to_clean.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
		smp_mb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
		if (netif_queue_stopped(netdev) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
			netif_wake_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
			++adapter->restart_queue;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
	if (!adapter->ecdev && adapter->detect_tx_hung) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
		/* Detect a transmit hang in hardware, this serializes the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
		 * check with the clearing of time_stamp and movement of i
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
		adapter->detect_tx_hung = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
		if (tx_ring->buffer_info[eop].time_stamp &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
			       (adapter->tx_timeout_factor * HZ)) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
			/* detected Tx unit hang */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
			e_err(drv, "Detected Tx Unit Hang\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
			      "  Tx Queue             <%lu>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
			      "  TDH                  <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
			      "  TDT                  <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
			      "  next_to_use          <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
			      "  next_to_clean        <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
			      "buffer_info[next_to_clean]\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
			      "  time_stamp           <%lx>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
			      "  next_to_watch        <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
			      "  jiffies              <%lx>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
			      "  next_to_watch.status <%x>\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
				(unsigned long)((tx_ring - adapter->tx_ring) /
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
					sizeof(struct e1000_tx_ring)),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
				readl(hw->hw_addr + tx_ring->tdh),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
				readl(hw->hw_addr + tx_ring->tdt),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
				tx_ring->next_to_use,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
				tx_ring->next_to_clean,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
				tx_ring->buffer_info[eop].time_stamp,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
				eop,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
				jiffies,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
				eop_desc->upper.fields.status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
			e1000_dump(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
			netif_stop_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
	adapter->total_tx_bytes += total_tx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	adapter->total_tx_packets += total_tx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
	netdev->stats.tx_bytes += total_tx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
	netdev->stats.tx_packets += total_tx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
	return count < tx_ring->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
 * e1000_rx_checksum - Receive Checksum Offload for 82543
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
 * @adapter:     board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
 * @status_err:  receive descriptor status and error fields
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
 * @csum:        receive descriptor csum field
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
 * @sk_buff:     socket buffer with received data
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
			      u32 csum, struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
	u16 status = (u16)status_err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
	u8 errors = (u8)(status_err >> 24);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
	skb_checksum_none_assert(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
	/* 82543 or newer only */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
	if (unlikely(hw->mac_type < e1000_82543)) return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
	/* Ignore Checksum bit is set */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
	/* TCP/UDP checksum error bit is set */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
		/* let the stack verify checksum errors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
		adapter->hw_csum_err++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	/* TCP/UDP Checksum has not been calculated */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	if (!(status & E1000_RXD_STAT_TCPCS))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	/* It must be a TCP or UDP packet with a valid checksum */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
		/* TCP checksum is good */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
		skb->ip_summed = CHECKSUM_UNNECESSARY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
	adapter->hw_csum_good++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
 * e1000_consume_page - helper function
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
			       u16 length)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
	bi->page = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
	skb->len += length;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	skb->data_len += length;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
	skb->truesize += PAGE_SIZE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
 * e1000_receive_skb - helper function to handle rx indications
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
 * @status: descriptor status field as written by hardware
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
 * @skb: pointer to sk_buff to be indicated to stack
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
			      __le16 vlan, struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	skb->protocol = eth_type_trans(skb, adapter->netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
	if (status & E1000_RXD_STAT_VP) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
		u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
	napi_gro_receive(&adapter->napi, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
 * @rx_ring: ring to clean
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
 * @work_done: amount of napi work completed this call
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
 * @work_to_do: max amount of work allowed for this call to do
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
 * the return value indicates whether actual cleaning was done, there
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
 * is no guarantee that everything was cleaned
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
				     struct e1000_rx_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
				     int *work_done, int work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
	struct e1000_rx_desc *rx_desc, *next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
	struct e1000_buffer *buffer_info, *next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
	unsigned long irq_flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
	u32 length;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
	int cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
	bool cleaned = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
	unsigned int total_rx_bytes=0, total_rx_packets=0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
	i = rx_ring->next_to_clean;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
	rx_desc = E1000_RX_DESC(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
	while (rx_desc->status & E1000_RXD_STAT_DD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		u8 status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		if (*work_done >= work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
		(*work_done)++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		rmb(); /* read descriptor and rx_buffer_info after status DD */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		status = rx_desc->status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
		skb = buffer_info->skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
		if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
			buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
		if (++i == rx_ring->count) i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
		next_rxd = E1000_RX_DESC(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
		prefetch(next_rxd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
		next_buffer = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
		cleaned = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
		cleaned_count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
		dma_unmap_page(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
			       buffer_info->length, DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
		buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		length = le16_to_cpu(rx_desc->length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
		/* errors is only valid for DD + EOP descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
		if (!adapter->ecdev &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
		    unlikely((status & E1000_RXD_STAT_EOP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
			u8 *mapped;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
			u8 last_byte;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
			mapped = page_address(buffer_info->page);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
			last_byte = *(mapped + length - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
				       last_byte)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
				spin_lock_irqsave(&adapter->stats_lock,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
						  irq_flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
				e1000_tbi_adjust_stats(hw, &adapter->stats,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
						       length, mapped);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
				spin_unlock_irqrestore(&adapter->stats_lock,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
						       irq_flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
				length--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
				if (netdev->features & NETIF_F_RXALL)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
					goto process_skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
				/* recycle both page and skb */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
				buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
				/* an error means any chain goes out the window
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
				 * too
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
				 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
				if (rx_ring->rx_skb_top)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
					dev_kfree_skb(rx_ring->rx_skb_top);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
				rx_ring->rx_skb_top = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
				goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
#define rxtop rx_ring->rx_skb_top
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
process_skb:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
		if (!(status & E1000_RXD_STAT_EOP)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
			/* this descriptor is only the beginning (or middle) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
			if (!rxtop) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
				/* this is the beginning of a chain */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
				rxtop = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
						   0, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
				/* this is the middle of a chain */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
				skb_fill_page_desc(rxtop,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
				    skb_shinfo(rxtop)->nr_frags,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
				    buffer_info->page, 0, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
				/* re-use the skb, only consumed the page */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
				buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
			e1000_consume_page(buffer_info, rxtop, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
			if (rxtop) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
				/* end of the chain */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
				skb_fill_page_desc(rxtop,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
				    skb_shinfo(rxtop)->nr_frags,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
				    buffer_info->page, 0, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
				/* re-use the current skb, we only consumed the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
				 * page
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
				 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
				buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
				skb = rxtop;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
				rxtop = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
				e1000_consume_page(buffer_info, skb, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
				/* no chain, got EOP, this buf is the packet
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
				 * copybreak to save the put_page/alloc_page
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
				 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
				if (length <= copybreak &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
				    skb_tailroom(skb) >= length) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
					u8 *vaddr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
					vaddr = kmap_atomic(buffer_info->page);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
					memcpy(skb_tail_pointer(skb), vaddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
					       length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
					kunmap_atomic(vaddr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
					/* re-use the page, so don't erase
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
					 * buffer_info->page
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
					 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
					skb_put(skb, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
				} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
					skb_fill_page_desc(skb, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
							   buffer_info->page, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
							   length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
					e1000_consume_page(buffer_info, skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
							   length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		e1000_rx_checksum(adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
				  (u32)(status) |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
				  ((u32)(rx_desc->errors) << 24),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
				  le16_to_cpu(rx_desc->csum), skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		total_rx_bytes += (skb->len - 4); /* don't count FCS */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
		if (likely(!(netdev->features & NETIF_F_RXFCS)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
			pskb_trim(skb, skb->len - 4);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
		total_rx_packets++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
		/* eth type trans needs skb->data to point to something */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		if (!pskb_may_pull(skb, ETH_HLEN)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
			e_err(drv, "pskb_may_pull failed.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
			if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
				dev_kfree_skb(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
		if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
			ecdev_receive(adapter->ecdev, skb->data, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
			// No need to detect link status as
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
			// long as frames are received: Reset watchdog.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
			adapter->ec_watchdog_jiffies = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
			e1000_receive_skb(adapter, status, rx_desc->special, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
next_desc:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
		rx_desc->status = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
		/* return some buffers to hardware, one at a time is too slow */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
			cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
		/* use prefetched values */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
		rx_desc = next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
		buffer_info = next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
	rx_ring->next_to_clean = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
	if (cleaned_count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
	adapter->total_rx_packets += total_rx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
	adapter->total_rx_bytes += total_rx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
	netdev->stats.rx_bytes += total_rx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
	netdev->stats.rx_packets += total_rx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
	return cleaned;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
/* this should improve performance for small packets with large amounts
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
 * of reassembly being done in the stack
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
static void e1000_check_copybreak(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
				 struct e1000_buffer *buffer_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
				 u32 length, struct sk_buff **skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	struct sk_buff *new_skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
	if (adapter->ecdev || length > copybreak)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	new_skb = netdev_alloc_skb_ip_align(netdev, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
	if (!new_skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
	skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
				       (*skb)->data - NET_IP_ALIGN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
				       length + NET_IP_ALIGN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
	/* save the skb in buffer_info as good */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
	buffer_info->skb = *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	*skb = new_skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
 * @rx_ring: ring to clean
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
 * @work_done: amount of napi work completed this call
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
 * @work_to_do: max amount of work allowed for this call to do
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
			       struct e1000_rx_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
			       int *work_done, int work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
	struct e1000_rx_desc *rx_desc, *next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
	struct e1000_buffer *buffer_info, *next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
	unsigned long flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
	u32 length;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
	int cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
	bool cleaned = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
	unsigned int total_rx_bytes=0, total_rx_packets=0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
	i = rx_ring->next_to_clean;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
	rx_desc = E1000_RX_DESC(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
	while (rx_desc->status & E1000_RXD_STAT_DD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
		struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
		u8 status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
		if (*work_done >= work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
		(*work_done)++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
		rmb(); /* read descriptor and rx_buffer_info after status DD */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
		status = rx_desc->status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
		skb = buffer_info->skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
		if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
			buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
		prefetch(skb->data - NET_IP_ALIGN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
		if (++i == rx_ring->count) i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
		next_rxd = E1000_RX_DESC(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
		prefetch(next_rxd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
		next_buffer = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
		cleaned = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
		cleaned_count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
		dma_unmap_single(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
				 buffer_info->length, DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
		buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
		length = le16_to_cpu(rx_desc->length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		/* !EOP means multiple descriptors were used to store a single
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
		 * packet, if thats the case we need to toss it.  In fact, we
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		 * to toss every packet with the EOP bit clear and the next
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
		 * frame that _does_ have the EOP bit set, as it is by
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
		 * definition only a frame fragment
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
			adapter->discarding = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
		if (adapter->discarding) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
			/* All receives must fit into a single buffer */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
			e_dbg("Receive packet consumed multiple buffers\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
			/* recycle */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
			buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
			if (status & E1000_RXD_STAT_EOP)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
				adapter->discarding = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
		if (!adapter->ecdev &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
		    unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
			u8 last_byte = *(skb->data + length - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
				       last_byte)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
				spin_lock_irqsave(&adapter->stats_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
				e1000_tbi_adjust_stats(hw, &adapter->stats,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
						       length, skb->data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
				spin_unlock_irqrestore(&adapter->stats_lock,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
						       flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
				length--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
				if (netdev->features & NETIF_F_RXALL)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
					goto process_skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
				/* recycle */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
				buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
				goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
process_skb:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
		total_rx_bytes += (length - 4); /* don't count FCS */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
		total_rx_packets++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
		if (likely(!(netdev->features & NETIF_F_RXFCS)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
			/* adjust length to remove Ethernet CRC, this must be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
			 * done after the TBI_ACCEPT workaround above
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
			length -= 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		e1000_check_copybreak(netdev, buffer_info, length, &skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
		skb_put(skb, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
		/* Receive Checksum Offload */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
		e1000_rx_checksum(adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
				  (u32)(status) |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
				  ((u32)(rx_desc->errors) << 24),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
				  le16_to_cpu(rx_desc->csum), skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
		if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
			ecdev_receive(adapter->ecdev, skb->data, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
			// No need to detect link status as
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
			// long as frames are received: Reset watchdog.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
			adapter->ec_watchdog_jiffies = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
			e1000_receive_skb(adapter, status, rx_desc->special, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
next_desc:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
		rx_desc->status = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
		/* return some buffers to hardware, one at a time is too slow */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
			cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		/* use prefetched values */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
		rx_desc = next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
		buffer_info = next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
	rx_ring->next_to_clean = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
	if (cleaned_count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
	adapter->total_rx_packets += total_rx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
	adapter->total_rx_bytes += total_rx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
	netdev->stats.rx_bytes += total_rx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
	netdev->stats.rx_packets += total_rx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
	return cleaned;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
 * @adapter: address of board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
 * @rx_ring: pointer to receive ring structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
 * @cleaned_count: number of buffers to allocate this pass
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
static void
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
			     struct e1000_rx_ring *rx_ring, int cleaned_count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	struct e1000_rx_desc *rx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
	struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	unsigned int bufsz = 256 - 16 /*for skb_reserve */ ;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
	i = rx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
	while (cleaned_count--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
		skb = buffer_info->skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
		if (skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
			skb_trim(skb, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
			goto check_page;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
		if (unlikely(!skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
			/* Better luck next round */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
			adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
		buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
		buffer_info->length = adapter->rx_buffer_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
check_page:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
		/* allocate a new page if necessary */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
		if (!buffer_info->page) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
			buffer_info->page = alloc_page(GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
			if (unlikely(!buffer_info->page)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
				adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
		if (!buffer_info->dma) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
			buffer_info->dma = dma_map_page(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
							buffer_info->page, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
							buffer_info->length,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
							DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
				put_page(buffer_info->page);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
				dev_kfree_skb(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
				buffer_info->page = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
				buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
				buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
				adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
				break; /* while !buffer_info->skb */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
		rx_desc = E1000_RX_DESC(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
		if (unlikely(++i == rx_ring->count))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
			i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
		buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	if (likely(rx_ring->next_to_use != i)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		rx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
		if (unlikely(i-- == 0))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
			i = (rx_ring->count - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
		/* Force memory writes to complete before letting h/w
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		 * know there are new descriptors to fetch.  (Only
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
		 * applicable for weak-ordered memory model archs,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
		 * such as IA-64).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
		wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
 * @adapter: address of board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
				   struct e1000_rx_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
				   int cleaned_count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
	struct e1000_rx_desc *rx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	unsigned int bufsz = adapter->rx_buffer_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	i = rx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	while (cleaned_count--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
		skb = buffer_info->skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		if (skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
			skb_trim(skb, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
			goto map_skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
		if (unlikely(!skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
			/* Better luck next round */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
			adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
		/* Fix for errata 23, can't cross 64kB boundary */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
			struct sk_buff *oldskb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
			e_err(rx_err, "skb align check failed: %u bytes at "
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
			      "%p\n", bufsz, skb->data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
			/* Try again, without freeing the previous */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
			/* Failed allocation, critical failure */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
			if (!skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
				dev_kfree_skb(oldskb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
				adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
				/* give up */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
				dev_kfree_skb(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
				dev_kfree_skb(oldskb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
				adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
				break; /* while !buffer_info->skb */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
			/* Use new allocation */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
			dev_kfree_skb(oldskb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
		buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
		buffer_info->length = adapter->rx_buffer_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
map_skb:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
		buffer_info->dma = dma_map_single(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
						  skb->data,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
						  buffer_info->length,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
						  DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
			dev_kfree_skb(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
			buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
			buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
			adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
			break; /* while !buffer_info->skb */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
		/* XXX if it was allocated cleanly it will never map to a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
		 * boundary crossing
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
		/* Fix for errata 23, can't cross 64kB boundary */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
		if (!e1000_check_64k_bound(adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
					(void *)(unsigned long)buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
					adapter->rx_buffer_len)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
			e_err(rx_err, "dma align check failed: %u bytes at "
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
			      "%p\n", adapter->rx_buffer_len,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
			      (void *)(unsigned long)buffer_info->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
			dev_kfree_skb(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
			buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
			dma_unmap_single(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
					 adapter->rx_buffer_len,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
					 DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
			buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
			adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
			break; /* while !buffer_info->skb */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
		rx_desc = E1000_RX_DESC(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
		if (unlikely(++i == rx_ring->count))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
			i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
		buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	if (likely(rx_ring->next_to_use != i)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
		rx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
		if (unlikely(i-- == 0))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
			i = (rx_ring->count - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
		/* Force memory writes to complete before letting h/w
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
		 * know there are new descriptors to fetch.  (Only
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
		 * applicable for weak-ordered memory model archs,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
		 * such as IA-64).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
		wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
		writel(i, hw->hw_addr + rx_ring->rdt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
 * @adapter:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
static void e1000_smartspeed(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	u16 phy_status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	u16 phy_ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	if (adapter->smartspeed == 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
		/* If Master/Slave config fault is asserted twice,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
		 * we assume back-to-back
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
					    phy_ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
			adapter->smartspeed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
			if (!e1000_phy_setup_autoneg(hw) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
			   !e1000_read_phy_reg(hw, PHY_CTRL,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
					       &phy_ctrl)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
					     MII_CR_RESTART_AUTO_NEG);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
				e1000_write_phy_reg(hw, PHY_CTRL,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
						    phy_ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
		/* If still no link, perhaps using 2/3 pair cable */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
		phy_ctrl |= CR_1000T_MS_ENABLE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
		if (!e1000_phy_setup_autoneg(hw) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
				     MII_CR_RESTART_AUTO_NEG);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
		adapter->smartspeed = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
 * e1000_ioctl -
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
 * @netdev:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
 * @ifreq:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
 * @cmd:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
	switch (cmd) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
	case SIOCGMIIPHY:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
	case SIOCGMIIREG:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
	case SIOCSMIIREG:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
		return e1000_mii_ioctl(netdev, ifr, cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
		return -EOPNOTSUPP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
 * e1000_mii_ioctl -
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
 * @netdev:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
 * @ifreq:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
 * @cmd:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
			   int cmd)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
	struct mii_ioctl_data *data = if_mii(ifr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	int retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
	u16 mii_reg;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	unsigned long flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
	if (hw->media_type != e1000_media_type_copper)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
		return -EOPNOTSUPP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
	switch (cmd) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
	case SIOCGMIIPHY:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
		data->phy_id = hw->phy_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	case SIOCGMIIREG:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
		if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
			return -EPERM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
		spin_lock_irqsave(&adapter->stats_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
				   &data->val_out)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
			return -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
	case SIOCSMIIREG:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
		if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
			return -EPERM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
		if (data->reg_num & ~(0x1F))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
			return -EFAULT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
		mii_reg = data->val_in;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
		spin_lock_irqsave(&adapter->stats_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
		if (e1000_write_phy_reg(hw, data->reg_num,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
					mii_reg)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
			return -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
		if (hw->media_type == e1000_media_type_copper) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
			switch (data->reg_num) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
			case PHY_CTRL:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
				if (mii_reg & MII_CR_POWER_DOWN)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
					break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
					hw->autoneg = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
					hw->autoneg_advertised = 0x2F;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
				} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
					u32 speed;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
					if (mii_reg & 0x40)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
						speed = SPEED_1000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
					else if (mii_reg & 0x2000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
						speed = SPEED_100;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
					else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
						speed = SPEED_10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
					retval = e1000_set_spd_dplx(
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
						adapter, speed,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
						((mii_reg & 0x100)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
						 ? DUPLEX_FULL :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
						 DUPLEX_HALF));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
					if (retval)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
						return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
				if (netif_running(adapter->netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
					e1000_reinit_locked(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
				else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
					e1000_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
			case M88E1000_PHY_SPEC_CTRL:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
			case M88E1000_EXT_PHY_SPEC_CTRL:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
				if (e1000_phy_reset(hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
					return -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
			switch (data->reg_num) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
			case PHY_CTRL:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
				if (mii_reg & MII_CR_POWER_DOWN)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
					break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
				if (netif_running(adapter->netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
					e1000_reinit_locked(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
				else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
					e1000_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
		return -EOPNOTSUPP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
	return E1000_SUCCESS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
void e1000_pci_set_mwi(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
	struct e1000_adapter *adapter = hw->back;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
	int ret_val = pci_set_mwi(adapter->pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
		e_err(probe, "Error in setting MWI\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
void e1000_pci_clear_mwi(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
	struct e1000_adapter *adapter = hw->back;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
	pci_clear_mwi(adapter->pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
	struct e1000_adapter *adapter = hw->back;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
	return pcix_get_mmrbc(adapter->pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
	struct e1000_adapter *adapter = hw->back;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
	pcix_set_mmrbc(adapter->pdev, mmrbc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
	outl(value, port);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
static bool e1000_vlan_used(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
	u16 vid;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
		return true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
	return false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
static void __e1000_vlan_mode(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
			      netdev_features_t features)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
	ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
	if (features & NETIF_F_HW_VLAN_CTAG_RX) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
		/* enable VLAN tag insert/strip */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
		ctrl |= E1000_CTRL_VME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
		/* disable VLAN tag insert/strip */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
		ctrl &= ~E1000_CTRL_VME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
	ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
				     bool filter_on)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
	u32 rctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
	if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
		e1000_irq_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
	__e1000_vlan_mode(adapter, adapter->netdev->features);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
	if (filter_on) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
		/* enable VLAN receive filtering */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
		rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
		rctl &= ~E1000_RCTL_CFIEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
		if (!(adapter->netdev->flags & IFF_PROMISC))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
			rctl |= E1000_RCTL_VFE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
		ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
		e1000_update_mng_vlan(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
		/* disable VLAN receive filtering */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
		rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
		rctl &= ~E1000_RCTL_VFE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
		ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
	if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
		e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
static void e1000_vlan_mode(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
			    netdev_features_t features)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
	if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
		e1000_irq_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
	__e1000_vlan_mode(adapter, features);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
	if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
		e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
static int e1000_vlan_rx_add_vid(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
				 __be16 proto, u16 vid)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
	u32 vfta, index;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
	if ((hw->mng_cookie.status &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
	    (vid == adapter->mng_vlan_id))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
	if (!e1000_vlan_used(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
		e1000_vlan_filter_on_off(adapter, true);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
	/* add VID to filter table */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
	index = (vid >> 5) & 0x7F;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
	vfta |= (1 << (vid & 0x1F));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
	e1000_write_vfta(hw, index, vfta);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
	set_bit(vid, adapter->active_vlans);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
static int e1000_vlan_rx_kill_vid(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
				  __be16 proto, u16 vid)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
	u32 vfta, index;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
	if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
		e1000_irq_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
	if (!test_bit(__E1000_DOWN, &adapter->flags))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
		e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
	/* remove VID from filter table */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
	index = (vid >> 5) & 0x7F;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
	vfta &= ~(1 << (vid & 0x1F));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
	e1000_write_vfta(hw, index, vfta);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
	clear_bit(vid, adapter->active_vlans);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
	if (!e1000_vlan_used(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
		e1000_vlan_filter_on_off(adapter, false);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
static void e1000_restore_vlan(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
	u16 vid;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
	if (!e1000_vlan_used(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
	e1000_vlan_filter_on_off(adapter, true);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
		e1000_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
	hw->autoneg = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	/* Make sure dplx is at most 1 bit and lsb of speed is not set
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	 * for the switch() below to work
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
	if ((spd & 1) || (dplx & ~1))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
		goto err_inval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
	/* Fiber NICs only allow 1000 gbps Full duplex */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
	if ((hw->media_type == e1000_media_type_fiber) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
	    spd != SPEED_1000 &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
	    dplx != DUPLEX_FULL)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
		goto err_inval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
	switch (spd + dplx) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
	case SPEED_10 + DUPLEX_HALF:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
		hw->forced_speed_duplex = e1000_10_half;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
	case SPEED_10 + DUPLEX_FULL:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
		hw->forced_speed_duplex = e1000_10_full;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
	case SPEED_100 + DUPLEX_HALF:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
		hw->forced_speed_duplex = e1000_100_half;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
	case SPEED_100 + DUPLEX_FULL:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
		hw->forced_speed_duplex = e1000_100_full;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
	case SPEED_1000 + DUPLEX_FULL:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
		hw->autoneg = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
		goto err_inval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
	/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
	hw->mdix = AUTO_ALL_MODES;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
err_inval:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
	e_err(probe, "Unsupported Speed/Duplex configuration\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
	return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
	u32 ctrl, ctrl_ext, rctl, status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
	u32 wufc = adapter->wol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
	int retval = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
		return -EBUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
	netif_device_detach(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
	if (netif_running(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
		e1000_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
	retval = pci_save_state(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
	if (retval)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
		return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
	status = er32(STATUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
	if (status & E1000_STATUS_LU)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
		wufc &= ~E1000_WUFC_LNKC;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
	if (wufc) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
		e1000_setup_rctl(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
		e1000_set_rx_mode(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
		rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
		/* turn on all-multi mode if wake on multicast is enabled */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
		if (wufc & E1000_WUFC_MC)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
			rctl |= E1000_RCTL_MPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
		/* enable receives in the hardware */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
		ew32(RCTL, rctl | E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
		if (hw->mac_type >= e1000_82540) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
			ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
			/* advertise wake from D3Cold */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
			#define E1000_CTRL_ADVD3WUC 0x00100000
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
			/* phy power management enable */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
			ctrl |= E1000_CTRL_ADVD3WUC |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
				E1000_CTRL_EN_PHY_PWR_MGMT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
			ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
		if (hw->media_type == e1000_media_type_fiber ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
		    hw->media_type == e1000_media_type_internal_serdes) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
			/* keep the laser running in D3 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
			ctrl_ext = er32(CTRL_EXT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
			ew32(CTRL_EXT, ctrl_ext);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
		ew32(WUC, E1000_WUC_PME_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
		ew32(WUFC, wufc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
		ew32(WUC, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
		ew32(WUFC, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
	e1000_release_manageability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
	*enable_wake = !!wufc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
	/* make sure adapter isn't asleep if manageability is enabled */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
	if (adapter->en_mng_pt)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
		*enable_wake = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
		e1000_free_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
	pci_disable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
	int retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
	bool wake;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
	retval = __e1000_shutdown(pdev, &wake);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	if (retval)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
		return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
	if (wake) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
		pci_prepare_to_sleep(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
		pci_wake_from_d3(pdev, false);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
		pci_set_power_state(pdev, PCI_D3hot);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
static int e1000_resume(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
	u32 err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
	if (adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
		return -EBUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
	pci_set_power_state(pdev, PCI_D0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
	pci_restore_state(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
	pci_save_state(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
	if (adapter->need_ioport)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
		err = pci_enable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
		err = pci_enable_device_mem(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
	if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
		pr_err("Cannot enable PCI device from suspend\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
		return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
	pci_set_master(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
	pci_enable_wake(pdev, PCI_D3hot, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
	pci_enable_wake(pdev, PCI_D3cold, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
	if (netif_running(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
		err = e1000_request_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
		if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
			return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
	e1000_power_up_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
	e1000_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
	ew32(WUS, ~0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
	e1000_init_manageability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
		e1000_up(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
	if (!adapter->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
		netif_device_attach(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
static void e1000_shutdown(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
	bool wake;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
	__e1000_shutdown(pdev, &wake);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
	if (system_state == SYSTEM_POWER_OFF) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
		pci_wake_from_d3(pdev, wake);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
		pci_set_power_state(pdev, PCI_D3hot);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
#ifdef CONFIG_NET_POLL_CONTROLLER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
/* Polling 'interrupt' - used by things like netconsole to send skbs
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
 * without having to re-enable interrupts. It's not called while
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
 * the interrupt routine is executing.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
static void e1000_netpoll(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
	disable_irq(adapter->pdev->irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
	e1000_intr(adapter->pdev->irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
	enable_irq(adapter->pdev->irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
 * e1000_io_error_detected - called when PCI error is detected
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
 * @pdev: Pointer to PCI device
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
 * @state: The current pci connection state
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
 * This function is called after a PCI bus error affecting
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
 * this device has been detected.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
						pci_channel_state_t state)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
	netif_device_detach(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
	if (state == pci_channel_io_perm_failure)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
		return PCI_ERS_RESULT_DISCONNECT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
		e1000_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
	pci_disable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
	/* Request a slot slot reset. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
	return PCI_ERS_RESULT_NEED_RESET;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
 * e1000_io_slot_reset - called after the pci bus has been reset.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
 * @pdev: Pointer to PCI device
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
 * Restart the card from scratch, as if from a cold-boot. Implementation
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
 * resembles the first-half of the e1000_resume routine.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
	if (adapter->need_ioport)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
		err = pci_enable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
		err = pci_enable_device_mem(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
	if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
		pr_err("Cannot re-enable PCI device after reset.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
		return PCI_ERS_RESULT_DISCONNECT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
	pci_set_master(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
	pci_enable_wake(pdev, PCI_D3hot, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
	pci_enable_wake(pdev, PCI_D3cold, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
	e1000_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
	ew32(WUS, ~0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
	return PCI_ERS_RESULT_RECOVERED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
 * e1000_io_resume - called when traffic can start flowing again.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
 * @pdev: Pointer to PCI device
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
 * This callback is called when the error recovery driver tells us that
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
 * its OK to resume normal operation. Implementation resembles the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
 * second-half of the e1000_resume routine.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
static void e1000_io_resume(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
	e1000_init_manageability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
	if (netif_running(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
		if (e1000_up(adapter)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
			pr_info("can't bring device back up after reset\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
			return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
	netif_device_attach(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
/* e1000_main.c */