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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2584
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include <net/ip6_checksum.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include <linux/io.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <linux/prefetch.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/bitops.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/if_vlan.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
char e1000_driver_name[] = "e1000";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#define DRV_VERSION "7.3.21-k8-NAPI"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
const char e1000_driver_version[] = DRV_VERSION;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
/* e1000_pci_tbl - PCI Device ID Table
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 * Last entry must be all 0s
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
 * Macro expands to...
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	INTEL_E1000_ETHERNET_DEVICE(0x2E6E),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	/* required last entry */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
	{0,}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
int e1000_up(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
void e1000_down(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
void e1000_reinit_locked(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
void e1000_reset(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
                             struct e1000_tx_ring *txdr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
                             struct e1000_rx_ring *rxdr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
                             struct e1000_tx_ring *tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
                             struct e1000_rx_ring *rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
void e1000_update_stats(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
static int e1000_init_module(void);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
static void e1000_exit_module(void);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static void e1000_remove(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static int e1000_alloc_queues(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static int e1000_sw_init(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static int e1000_open(struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static int e1000_close(struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static void e1000_configure_tx(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static void e1000_configure_rx(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
static void e1000_setup_rctl(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
                                struct e1000_tx_ring *tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
                                struct e1000_rx_ring *rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static void e1000_set_rx_mode(struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static void e1000_update_phy_info_task(struct work_struct *work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static void e1000_watchdog(struct work_struct *work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
				    struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
static int e1000_set_mac(struct net_device *netdev, void *p);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static irqreturn_t e1000_intr(int irq, void *data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
			       struct e1000_tx_ring *tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static int e1000_clean(struct napi_struct *napi, int budget);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
			       struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
			       int *work_done, int work_to_do);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
				     struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
				     int *work_done, int work_to_do);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
				   struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
				   int cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
					 struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
					 int cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
			   int cmd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
static void e1000_tx_timeout(struct net_device *dev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
static void e1000_reset_task(struct work_struct *work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static void e1000_smartspeed(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
                                       struct sk_buff *skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
static bool e1000_vlan_used(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
static void e1000_vlan_mode(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
			    netdev_features_t features);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
				     bool filter_on);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
static void e1000_restore_vlan(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
static int e1000_resume(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
static void e1000_shutdown(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
#ifdef CONFIG_NET_POLL_CONTROLLER
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
/* for netdump / net console */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
static void e1000_netpoll (struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
#define COPYBREAK_DEFAULT 256
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
module_param(copybreak, uint, 0644);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
MODULE_PARM_DESC(copybreak,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	"Maximum size of packet that is copied to a new buffer on receive");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
                     pci_channel_state_t state);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
static void e1000_io_resume(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
static const struct pci_error_handlers e1000_err_handler = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	.error_detected = e1000_io_error_detected,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	.slot_reset = e1000_io_slot_reset,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	.resume = e1000_io_resume,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
static struct pci_driver e1000_driver = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	.name     = e1000_driver_name,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	.id_table = e1000_pci_tbl,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	.probe    = e1000_probe,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	.remove   = e1000_remove,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	/* Power Management Hooks */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	.suspend  = e1000_suspend,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	.resume   = e1000_resume,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	.shutdown = e1000_shutdown,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	.err_handler = &e1000_err_handler
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
MODULE_LICENSE("GPL");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
MODULE_VERSION(DRV_VERSION);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
static int debug = -1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
module_param(debug, int, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
 * e1000_get_hw_dev - return device
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
 * used by hardware layer to print debugging information
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
struct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	return adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
 * e1000_init_module - Driver Registration Routine
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
 * e1000_init_module is the first routine called when the driver is
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
 * loaded. All it does is register with the PCI subsystem.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
static int __init e1000_init_module(void)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	int ret;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
	pr_info("%s - version %s\n", e1000_driver_string, e1000_driver_version);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	pr_info("%s\n", e1000_copyright);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	ret = pci_register_driver(&e1000_driver);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	if (copybreak != COPYBREAK_DEFAULT) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
		if (copybreak == 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
			pr_info("copybreak disabled\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
			pr_info("copybreak enabled for "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
				   "packets <= %u bytes\n", copybreak);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	return ret;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
module_init(e1000_init_module);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
 * e1000_exit_module - Driver Exit Cleanup Routine
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
 * e1000_exit_module is called just before the driver is removed
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
 * from memory.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
static void __exit e1000_exit_module(void)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	pci_unregister_driver(&e1000_driver);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
module_exit(e1000_exit_module);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
static int e1000_request_irq(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	irq_handler_t handler = e1000_intr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	int irq_flags = IRQF_SHARED;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	int err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	                  netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
		e_err(probe, "Unable to allocate interrupt Error: %d\n", err);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
static void e1000_free_irq(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	free_irq(adapter->pdev->irq, netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
 * e1000_irq_disable - Mask off interrupt generation on the NIC
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
static void e1000_irq_disable(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	ew32(IMC, ~0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	synchronize_irq(adapter->pdev->irq);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
 * e1000_irq_enable - Enable default interrupt generation settings
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
static void e1000_irq_enable(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	ew32(IMS, IMS_ENABLE_MASK);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	u16 vid = hw->mng_cookie.vlan_id;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	u16 old_vid = adapter->mng_vlan_id;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
	if (!e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	if (!test_bit(vid, adapter->active_vlans)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		if (hw->mng_cookie.status &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
		    E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
			e1000_vlan_rx_add_vid(netdev, vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
			adapter->mng_vlan_id = vid;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
		if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		    (vid != old_vid) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		    !test_bit(old_vid, adapter->active_vlans))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
			e1000_vlan_rx_kill_vid(netdev, old_vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		adapter->mng_vlan_id = vid;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
static void e1000_init_manageability(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
	if (adapter->en_mng_pt) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
		u32 manc = er32(MANC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		/* disable hardware interception of ARP */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
		manc &= ~(E1000_MANC_ARP_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
		ew32(MANC, manc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
static void e1000_release_manageability(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	if (adapter->en_mng_pt) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
		u32 manc = er32(MANC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
		/* re-enable hardware interception of ARP */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		manc |= E1000_MANC_ARP_EN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
		ew32(MANC, manc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
 * e1000_configure - configure the hardware for RX and TX
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
 * @adapter = private board structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
static void e1000_configure(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	e1000_set_rx_mode(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	e1000_restore_vlan(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	e1000_init_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	e1000_configure_tx(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	e1000_setup_rctl(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	e1000_configure_rx(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	/* call E1000_DESC_UNUSED which always leaves
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	 * at least 1 descriptor unused to make sure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	 * next_to_use != next_to_clean */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	for (i = 0; i < adapter->num_rx_queues; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
		adapter->alloc_rx_buf(adapter, ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
		                      E1000_DESC_UNUSED(ring));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
int e1000_up(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	/* hardware has been reset, we need to reload some things */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	e1000_configure(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	clear_bit(__E1000_DOWN, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	napi_enable(&adapter->napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	netif_wake_queue(adapter->netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	/* fire a link change interrupt to start the watchdog */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	ew32(ICS, E1000_ICS_LSC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
 * e1000_power_up_phy - restore link in case the phy was powered down
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
 * @adapter: address of board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
 * The phy may be powered down to save power and turn off link when the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
 * driver is unloaded and wake on lan is not enabled (among others)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
 * *** this routine MUST be followed by a call to e1000_reset ***
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
void e1000_power_up_phy(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	u16 mii_reg = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	/* Just clear the power down bit to wake the phy back up */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	if (hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
		/* according to the manual, the phy will retain its
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
		 * settings across a power-down/up cycle */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		mii_reg &= ~MII_CR_POWER_DOWN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
static void e1000_power_down_phy(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	/* Power down the PHY so no link is implied when interface is down *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	 * The PHY cannot be powered down if any of the following is true *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	 * (a) WoL is enabled
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	 * (b) AMT is active
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	 * (c) SoL/IDER session is active */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	   hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
		u16 mii_reg = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
		switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
		case e1000_82540:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
		case e1000_82545:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
		case e1000_82545_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
		case e1000_82546:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		case e1000_ce4100:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		case e1000_82546_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		case e1000_82541:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		case e1000_82541_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		case e1000_82547:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		case e1000_82547_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
				goto out;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
			goto out;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
		mii_reg |= MII_CR_POWER_DOWN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
		msleep(1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
out:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
static void e1000_down_and_stop(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	set_bit(__E1000_DOWN, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	/* Only kill reset task if adapter is not resetting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	if (!test_bit(__E1000_RESETTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		cancel_work_sync(&adapter->reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	cancel_delayed_work_sync(&adapter->watchdog_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	cancel_delayed_work_sync(&adapter->phy_info_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	cancel_delayed_work_sync(&adapter->fifo_stall_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
void e1000_down(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	u32 rctl, tctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	/* disable receives in the hardware */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	/* flush and sleep below */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	netif_tx_disable(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	/* disable transmits in the hardware */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	tctl = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	tctl &= ~E1000_TCTL_EN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	ew32(TCTL, tctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	/* flush both disables and wait for them to finish */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	msleep(10);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	napi_disable(&adapter->napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	 * Setting DOWN must be after irq_disable to prevent
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	 * a screaming interrupt.  Setting DOWN also prevents
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	 * tasks from rescheduling.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	e1000_down_and_stop(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	adapter->link_speed = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	adapter->link_duplex = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	netif_carrier_off(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	e1000_clean_all_tx_rings(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	e1000_clean_all_rx_rings(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
static void e1000_reinit_safe(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
		msleep(1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	mutex_lock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	e1000_up(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	mutex_unlock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	clear_bit(__E1000_RESETTING, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
void e1000_reinit_locked(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	/* if rtnl_lock is not held the call path is bogus */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	ASSERT_RTNL();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	WARN_ON(in_interrupt());
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
		msleep(1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	e1000_up(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	clear_bit(__E1000_RESETTING, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
void e1000_reset(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	bool legacy_pba_adjust = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	u16 hwm;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	/* Repartition Pba for greater than 9k mtu
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	 * To take effect CTRL.RST is required.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	case e1000_82542_rev2_0:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	case e1000_82542_rev2_1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	case e1000_82543:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	case e1000_82544:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	case e1000_82540:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	case e1000_82541:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	case e1000_82541_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
		legacy_pba_adjust = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
		pba = E1000_PBA_48K;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	case e1000_82545:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	case e1000_82545_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	case e1000_82546:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	case e1000_ce4100:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	case e1000_82546_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		pba = E1000_PBA_48K;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	case e1000_82547:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	case e1000_82547_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		legacy_pba_adjust = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
		pba = E1000_PBA_30K;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	case e1000_undefined:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	case e1000_num_macs:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	if (legacy_pba_adjust) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
		if (hw->max_frame_size > E1000_RXBUFFER_8192)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
			pba -= 8; /* allocate more FIFO for Tx */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		if (hw->mac_type == e1000_82547) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
			adapter->tx_fifo_head = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
			adapter->tx_fifo_size =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
			atomic_set(&adapter->tx_fifo_stall, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		/* adjust PBA for jumbo frames */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		ew32(PBA, pba);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
		/* To maintain wire speed transmits, the Tx FIFO should be
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		 * large enough to accommodate two full transmit packets,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		 * the Rx FIFO should be large enough to accommodate at least
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
		 * one full receive packet and is similarly rounded up and
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		 * expressed in KB. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		pba = er32(PBA);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		/* upper 16 bits has Tx packet buffer allocation size in KB */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		tx_space = pba >> 16;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		/* lower 16 bits has Rx packet buffer allocation size in KB */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
		pba &= 0xffff;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
		 * the tx fifo also stores 16 bytes of information about the tx
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		 * but don't include ethernet FCS because hardware appends it
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		min_tx_space = (hw->max_frame_size +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
		                sizeof(struct e1000_tx_desc) -
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
		                ETH_FCS_LEN) * 2;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
		min_tx_space = ALIGN(min_tx_space, 1024);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
		min_tx_space >>= 10;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
		/* software strips receive CRC, so leave room for it */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		min_rx_space = hw->max_frame_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		min_rx_space = ALIGN(min_rx_space, 1024);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		min_rx_space >>= 10;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		/* If current Tx allocation is less than the min Tx FIFO size,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		 * and the min Tx FIFO size is less than the current Rx FIFO
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		 * allocation, take space away from current Rx allocation */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
		if (tx_space < min_tx_space &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
		    ((min_tx_space - tx_space) < pba)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
			pba = pba - (min_tx_space - tx_space);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
			/* PCI/PCIx hardware has PBA alignment constraints */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
			switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
			case e1000_82545 ... e1000_82546_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
				pba &= ~(E1000_PBA_8K - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
			default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
			/* if short on rx space, rx wins and must trump tx
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
			 * adjustment or use Early Receive if available */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
			if (pba < min_rx_space)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
				pba = min_rx_space;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	ew32(PBA, pba);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	 * flow control settings:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
	 * The high water mark must be low enough to fit one full frame
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	 * (or the size used for early receive) above it in the Rx FIFO.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	 * Set it to the lower of:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	 * - 90% of the Rx FIFO size, and
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	 * - the full Rx FIFO size minus the early receive size (for parts
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	 * - the full Rx FIFO size minus one full frame
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	hwm = min(((pba << 10) * 9 / 10),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		  ((pba << 10) - hw->max_frame_size));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	hw->fc_low_water = hw->fc_high_water - 8;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	hw->fc_send_xon = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	hw->fc = hw->original_fc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	/* Allow time for pending master requests to run */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
	e1000_reset_hw(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	if (hw->mac_type >= e1000_82544)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
		ew32(WUC, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	if (e1000_init_hw(hw))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		e_dev_err("Hardware Error\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
	e1000_update_mng_vlan(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
	if (hw->mac_type >= e1000_82544 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	    hw->autoneg == 1 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
		u32 ctrl = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
		/* clear phy power management bit if we are in gig only mode,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
		 * which if enabled will attempt negotiation to 100Mb, which
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
		 * can cause a loss of link at power off or driver unload */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
		ctrl &= ~E1000_CTRL_SWDPIN3;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
		ew32(CTRL, ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	e1000_reset_adaptive(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	e1000_phy_get_info(hw, &adapter->phy_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	e1000_release_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
/* Dump the eeprom for users having checksum issues */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	struct ethtool_eeprom eeprom;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	const struct ethtool_ops *ops = netdev->ethtool_ops;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	u8 *data;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	u16 csum_old, csum_new = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	eeprom.len = ops->get_eeprom_len(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
	eeprom.offset = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	data = kmalloc(eeprom.len, GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	if (!data)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	ops->get_eeprom(netdev, &eeprom, data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		csum_new += data[i] + (data[i + 1] << 8);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	csum_new = EEPROM_SUM - csum_new;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	pr_err("/*********************/\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	pr_err("Current EEPROM Checksum : 0x%04x\n", csum_old);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	pr_err("Calculated              : 0x%04x\n", csum_new);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	pr_err("Offset    Values\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	pr_err("========  ======\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	pr_err("Include this output when contacting your support provider.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	pr_err("This is not a software error! Something bad happened to\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	pr_err("your hardware or EEPROM image. Ignoring this problem could\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	pr_err("result in further problems, possibly loss of data,\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	pr_err("corruption or system hangs!\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	pr_err("The MAC Address will be reset to 00:00:00:00:00:00,\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	pr_err("which is invalid and requires you to set the proper MAC\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	pr_err("address manually before continuing to enable this network\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	pr_err("device. Please inspect the EEPROM dump and report the\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	pr_err("issue to your hardware vendor or Intel Customer Support.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	pr_err("/*********************/\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	kfree(data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
 * @pdev: PCI device information struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
 * Return true if an adapter needs ioport resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
static int e1000_is_need_ioport(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	switch (pdev->device) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	case E1000_DEV_ID_82540EM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	case E1000_DEV_ID_82540EM_LOM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	case E1000_DEV_ID_82540EP:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	case E1000_DEV_ID_82540EP_LOM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	case E1000_DEV_ID_82540EP_LP:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	case E1000_DEV_ID_82541EI:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	case E1000_DEV_ID_82541EI_MOBILE:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	case E1000_DEV_ID_82541ER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	case E1000_DEV_ID_82541ER_LOM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	case E1000_DEV_ID_82541GI:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	case E1000_DEV_ID_82541GI_LF:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	case E1000_DEV_ID_82541GI_MOBILE:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	case E1000_DEV_ID_82544EI_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	case E1000_DEV_ID_82544EI_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	case E1000_DEV_ID_82544GC_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	case E1000_DEV_ID_82544GC_LOM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	case E1000_DEV_ID_82545EM_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	case E1000_DEV_ID_82545EM_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	case E1000_DEV_ID_82546EB_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	case E1000_DEV_ID_82546EB_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
		return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
		return false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
static netdev_features_t e1000_fix_features(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	netdev_features_t features)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	 * Since there is no support for separate rx/tx vlan accel
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	 * enable/disable make sure tx flag is always in same state as rx.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	if (features & NETIF_F_HW_VLAN_RX)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
		features |= NETIF_F_HW_VLAN_TX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
		features &= ~NETIF_F_HW_VLAN_TX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	return features;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
static int e1000_set_features(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	netdev_features_t features)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	netdev_features_t changed = features ^ netdev->features;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	if (changed & NETIF_F_HW_VLAN_RX)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		e1000_vlan_mode(netdev, features);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	if (!(changed & (NETIF_F_RXCSUM | NETIF_F_RXALL)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
		return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	netdev->features = features;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
		e1000_reinit_locked(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
static const struct net_device_ops e1000_netdev_ops = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	.ndo_open		= e1000_open,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	.ndo_stop		= e1000_close,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	.ndo_start_xmit		= e1000_xmit_frame,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	.ndo_get_stats		= e1000_get_stats,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	.ndo_set_rx_mode	= e1000_set_rx_mode,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	.ndo_set_mac_address	= e1000_set_mac,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	.ndo_tx_timeout		= e1000_tx_timeout,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	.ndo_change_mtu		= e1000_change_mtu,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	.ndo_do_ioctl		= e1000_ioctl,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	.ndo_validate_addr	= eth_validate_addr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
#ifdef CONFIG_NET_POLL_CONTROLLER
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	.ndo_poll_controller	= e1000_netpoll,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	.ndo_fix_features	= e1000_fix_features,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	.ndo_set_features	= e1000_set_features,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
 * e1000_init_hw_struct - initialize members of hw struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
 * @adapter: board private struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
 * @hw: structure used by e1000_hw.c
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
 * Factors out initialization of the e1000_hw struct to its own function
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
 * that can be called very early at init (just after struct allocation).
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
 * Fields are initialized based on PCI device information and
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
 * OS network device settings (MTU size).
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
 * Returns negative error codes if MAC type setup fails.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
static int e1000_init_hw_struct(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
				struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	/* PCI config space info */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	hw->vendor_id = pdev->vendor;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	hw->device_id = pdev->device;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	hw->subsystem_id = pdev->subsystem_device;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	hw->revision_id = pdev->revision;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	hw->max_frame_size = adapter->netdev->mtu +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	/* identify the MAC */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	if (e1000_set_mac_type(hw)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
		e_err(probe, "Unknown MAC Type\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		return -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	case e1000_82541:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	case e1000_82547:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	case e1000_82541_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	case e1000_82547_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
		hw->phy_init_script = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	e1000_set_media_type(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	e1000_get_bus_info(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	hw->wait_autoneg_complete = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	hw->tbi_compatibility_en = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	hw->adaptive_ifs = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	/* Copper options */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	if (hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
		hw->mdix = AUTO_ALL_MODES;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
		hw->disable_polarity_correction = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		hw->master_slave = E1000_MASTER_SLAVE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
 * e1000_probe - Device Initialization Routine
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
 * @pdev: PCI device information struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
 * @ent: entry in e1000_pci_tbl
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
 * Returns 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
 * e1000_probe initializes an adapter identified by a pci_dev structure.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
 * The OS initialization, configuring of the adapter private structure,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
 * and a hardware reset occur.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	struct net_device *netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	struct e1000_adapter *adapter;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	struct e1000_hw *hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	static int cards_found = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	int i, err, pci_using_dac;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	u16 eeprom_data = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	u16 tmp = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	int bars, need_ioport;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	/* do not allocate ioport bars when not needed */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	need_ioport = e1000_is_need_ioport(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	if (need_ioport) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
		err = pci_enable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
		err = pci_enable_device_mem(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
		return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
		goto err_pci_reg;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	pci_set_master(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	err = pci_save_state(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
		goto err_alloc_etherdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	err = -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	if (!netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		goto err_alloc_etherdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	SET_NETDEV_DEV(netdev, &pdev->dev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	pci_set_drvdata(pdev, netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	adapter->netdev = netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	adapter->pdev = pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	adapter->bars = bars;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	adapter->need_ioport = need_ioport;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	hw->back = adapter;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	err = -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	if (!hw->hw_addr)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
		goto err_ioremap;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	if (adapter->need_ioport) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
		for (i = BAR_1; i <= BAR_5; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
			if (pci_resource_len(pdev, i) == 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
				continue;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
				hw->io_base = pci_resource_start(pdev, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	/* make ready for any if (hw->...) below */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	err = e1000_init_hw_struct(adapter, hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		goto err_sw_init;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	 * there is a workaround being applied below that limits
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	 * 64-bit DMA addresses to 64-bit hardware.  There are some
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	 * 32-bit adapters that Tx hang when given 64-bit DMA addresses
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	pci_using_dac = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	if ((hw->bus_type == e1000_bus_type_pcix) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	    !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
		 * according to DMA-API-HOWTO, coherent calls will always
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
		 * succeed if the set call did
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
		pci_using_dac = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
			pr_err("No usable DMA config, aborting\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
			goto err_dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	netdev->netdev_ops = &e1000_netdev_ops;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	e1000_set_ethtool_ops(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	netdev->watchdog_timeo = 5 * HZ;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	adapter->bd_number = cards_found;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	/* setup the private structure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	err = e1000_sw_init(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		goto err_sw_init;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	err = -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	if (hw->mac_type == e1000_ce4100) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		hw->ce4100_gbe_mdio_base_virt =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
					ioremap(pci_resource_start(pdev, BAR_1),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		                                pci_resource_len(pdev, BAR_1));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		if (!hw->ce4100_gbe_mdio_base_virt)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
			goto err_mdio_ioremap;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	if (hw->mac_type >= e1000_82543) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		netdev->hw_features = NETIF_F_SG |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
				   NETIF_F_HW_CSUM |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
				   NETIF_F_HW_VLAN_RX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		netdev->features = NETIF_F_HW_VLAN_TX |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
				   NETIF_F_HW_VLAN_FILTER;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	if ((hw->mac_type >= e1000_82544) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	   (hw->mac_type != e1000_82547))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		netdev->hw_features |= NETIF_F_TSO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	netdev->priv_flags |= IFF_SUPP_NOFCS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	netdev->features |= netdev->hw_features;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	netdev->hw_features |= (NETIF_F_RXCSUM |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
				NETIF_F_RXALL |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
				NETIF_F_RXFCS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	if (pci_using_dac) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
		netdev->features |= NETIF_F_HIGHDMA;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
		netdev->vlan_features |= NETIF_F_HIGHDMA;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	netdev->vlan_features |= (NETIF_F_TSO |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
				  NETIF_F_HW_CSUM |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
				  NETIF_F_SG);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	netdev->priv_flags |= IFF_UNICAST_FLT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
	/* initialize eeprom parameters */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
	if (e1000_init_eeprom_params(hw)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		e_err(probe, "EEPROM initialization failed\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		goto err_eeprom;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	/* before reading the EEPROM, reset the controller to
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	 * put the device in a known good starting state */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	e1000_reset_hw(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	/* make sure the EEPROM is good */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	if (e1000_validate_eeprom_checksum(hw) < 0) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		e_err(probe, "The EEPROM Checksum Is Not Valid\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
		e1000_dump_eeprom(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
		 * set MAC address to all zeroes to invalidate and temporary
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
		 * disable this device for the user. This blocks regular
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
		 * traffic while still permitting ethtool ioctls from reaching
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		 * the hardware as well as allowing the user to run the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
		 * interface after manually setting a hw addr using
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
		 * `ip set address`
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
		memset(hw->mac_addr, 0, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
		/* copy the MAC address out of the EEPROM */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
		if (e1000_read_mac_addr(hw))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			e_err(probe, "EEPROM Read Error\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	/* don't block initalization here due to bad MAC address */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	if (!is_valid_ether_addr(netdev->perm_addr))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		e_err(probe, "Invalid MAC Address\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	INIT_DELAYED_WORK(&adapter->watchdog_task, e1000_watchdog);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	INIT_DELAYED_WORK(&adapter->fifo_stall_task,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
			  e1000_82547_tx_fifo_stall_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	INIT_DELAYED_WORK(&adapter->phy_info_task, e1000_update_phy_info_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	e1000_check_options(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
	/* Initial Wake on LAN setting
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	 * If APM wake is enabled in the EEPROM,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	 * enable the ACPI Magic Packet filter
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	case e1000_82542_rev2_0:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	case e1000_82542_rev2_1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	case e1000_82543:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	case e1000_82544:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		e1000_read_eeprom(hw,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	case e1000_82546:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	case e1000_82546_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
			e1000_read_eeprom(hw,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		/* Fall Through */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
		e1000_read_eeprom(hw,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	if (eeprom_data & eeprom_apme_mask)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		adapter->eeprom_wol |= E1000_WUFC_MAG;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
	/* now that we have the eeprom settings, apply the special cases
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	 * where the eeprom may be wrong or the board simply won't support
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
	 * wake on lan on a particular port */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	switch (pdev->device) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	case E1000_DEV_ID_82546GB_PCIE:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
		adapter->eeprom_wol = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
	case E1000_DEV_ID_82546EB_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	case E1000_DEV_ID_82546GB_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
		/* Wake events only supported on port A for dual fiber
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
		 * regardless of eeprom setting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
			adapter->eeprom_wol = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
		/* if quad port adapter, disable WoL on all but port A */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		if (global_quad_port_a != 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
			adapter->eeprom_wol = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
			adapter->quad_port_a = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
		/* Reset for multiple quad port adapters */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
		if (++global_quad_port_a == 4)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
			global_quad_port_a = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	/* initialize the wol settings based on the eeprom settings */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
	adapter->wol = adapter->eeprom_wol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	/* Auto detect PHY address */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	if (hw->mac_type == e1000_ce4100) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		for (i = 0; i < 32; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
			hw->phy_addr = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
			e1000_read_phy_reg(hw, PHY_ID2, &tmp);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
			if (tmp == 0 || tmp == 0xFF) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
				if (i == 31)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
					goto err_eeprom;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
				continue;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
			} else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
	/* reset the hardware with the new settings */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
	strcpy(netdev->name, "eth%d");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	err = register_netdev(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		goto err_register;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	e1000_vlan_filter_on_off(adapter, false);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	/* print bus type/speed/width info */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
	       netdev->dev_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	/* carrier off reporting is important to ethtool even BEFORE open */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
	netif_carrier_off(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	e_info(probe, "Intel(R) PRO/1000 Network Connection\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	cards_found++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
err_register:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
err_eeprom:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	e1000_phy_hw_reset(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
	if (hw->flash_address)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
		iounmap(hw->flash_address);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	kfree(adapter->tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	kfree(adapter->rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
err_dma:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
err_sw_init:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
err_mdio_ioremap:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	iounmap(hw->ce4100_gbe_mdio_base_virt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	iounmap(hw->hw_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
err_ioremap:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	free_netdev(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
err_alloc_etherdev:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	pci_release_selected_regions(pdev, bars);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
err_pci_reg:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	pci_disable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 * e1000_remove - Device Removal Routine
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 * @pdev: PCI device information struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 * e1000_remove is called by the PCI subsystem to alert the driver
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
 * that it should release a PCI device.  The could be caused by a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
 * Hot-Plug event, or because the driver is going to be removed from
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
 * memory.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
static void e1000_remove(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	e1000_down_and_stop(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	e1000_release_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	unregister_netdev(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	e1000_phy_hw_reset(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	kfree(adapter->tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	kfree(adapter->rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
	if (hw->mac_type == e1000_ce4100)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		iounmap(hw->ce4100_gbe_mdio_base_virt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
	iounmap(hw->hw_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	if (hw->flash_address)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
		iounmap(hw->flash_address);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	pci_release_selected_regions(pdev, adapter->bars);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	free_netdev(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	pci_disable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
 * @adapter: board private structure to initialize
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
 * e1000_sw_init initializes the Adapter private data structure.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
 * e1000_init_hw_struct MUST be called before this function
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
static int e1000_sw_init(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
	adapter->num_tx_queues = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
	adapter->num_rx_queues = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
	if (e1000_alloc_queues(adapter)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
		e_err(probe, "Unable to allocate memory for queues\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	/* Explicitly disable IRQ since the NIC can be in any state. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	spin_lock_init(&adapter->stats_lock);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	mutex_init(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	set_bit(__E1000_DOWN, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
 * e1000_alloc_queues - Allocate memory for all rings
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
 * @adapter: board private structure to initialize
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
 * We allocate one ring per queue at run-time since we don't know the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
 * number of queues at compile-time.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
static int e1000_alloc_queues(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	if (!adapter->tx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
	if (!adapter->rx_ring) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		kfree(adapter->tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	return E1000_SUCCESS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
 * e1000_open - Called when a network interface is made active
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
 * Returns 0 on success, negative value on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
 * The open entry point is called when a network interface is made
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
 * active by the system (IFF_UP).  At this point all resources needed
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
 * for transmit and receive operations are allocated, the interrupt
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
 * handler is registered with the OS, the watchdog task is started,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
 * and the stack is notified that the interface is ready.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
static int e1000_open(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	int err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	/* disallow open during test */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	if (test_bit(__E1000_TESTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
		return -EBUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	netif_carrier_off(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	/* allocate transmit descriptors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	err = e1000_setup_all_tx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
		goto err_setup_tx;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	/* allocate receive descriptors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	err = e1000_setup_all_rx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
		goto err_setup_rx;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	e1000_power_up_phy(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	if ((hw->mng_cookie.status &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
		e1000_update_mng_vlan(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
	/* before we allocate an interrupt, we must be ready to handle it.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	 * as soon as we call pci_request_irq, so we have to setup our
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
	 * clean_rx handler before we do so.  */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	e1000_configure(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	err = e1000_request_irq(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		goto err_req_irq;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	/* From here on the code is the same as e1000_up() */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	clear_bit(__E1000_DOWN, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	napi_enable(&adapter->napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	netif_start_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	/* fire a link status change interrupt to start the watchdog */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	ew32(ICS, E1000_ICS_LSC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	return E1000_SUCCESS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
err_req_irq:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	e1000_power_down_phy(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
	e1000_free_all_rx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
err_setup_rx:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	e1000_free_all_tx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
err_setup_tx:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
 * e1000_close - Disables a network interface
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
 * Returns 0, this is not allowed to fail
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
 * The close entry point is called when an interface is de-activated
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
 * by the OS.  The hardware is still under the drivers control, but
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
 * needs to be disabled.  A global MAC reset is issued to stop the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
 * hardware, and all transmit and receive resources are freed.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
static int e1000_close(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
	e1000_power_down_phy(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	e1000_free_irq(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	e1000_free_all_tx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	e1000_free_all_rx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	/* kill manageability vlan ID if supported, but not if a vlan with
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
	 * the same ID is registered on the host OS (let 8021q kill it) */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	if ((hw->mng_cookie.status &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	     !test_bit(adapter->mng_vlan_id, adapter->active_vlans)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
 * @adapter: address of board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
 * @start: address of beginning of memory
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
 * @len: length of memory
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
				  unsigned long len)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	unsigned long begin = (unsigned long)start;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	unsigned long end = begin + len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	/* First rev 82545 and 82546 need to not allow any memory
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	 * write location to cross 64k boundary due to errata 23 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	if (hw->mac_type == e1000_82545 ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	    hw->mac_type == e1000_ce4100 ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	    hw->mac_type == e1000_82546) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
	return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
 * @txdr:    tx descriptor ring (for a specific queue) to setup
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
 * Return 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
				    struct e1000_tx_ring *txdr)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
	int size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	size = sizeof(struct e1000_buffer) * txdr->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
	txdr->buffer_info = vzalloc(size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	if (!txdr->buffer_info) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		e_err(probe, "Unable to allocate memory for the Tx descriptor "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
		      "ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	/* round up to nearest 4K */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	txdr->size = ALIGN(txdr->size, 4096);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
					GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	if (!txdr->desc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
setup_tx_desc_die:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
		vfree(txdr->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
		e_err(probe, "Unable to allocate memory for the Tx descriptor "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
		      "ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	/* Fix for errata 23, can't cross 64kB boundary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
		void *olddesc = txdr->desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
		dma_addr_t olddma = txdr->dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
		e_err(tx_err, "txdr align check failed: %u bytes at %p\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
		      txdr->size, txdr->desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		/* Try again, without freeing the previous */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
						&txdr->dma, GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		/* Failed allocation, critical failure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
		if (!txdr->desc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
			goto setup_tx_desc_die;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
			/* give up */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
			dma_free_coherent(&pdev->dev, txdr->size, txdr->desc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
					  txdr->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
			e_err(probe, "Unable to allocate aligned memory "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
			      "for the transmit descriptor ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
			vfree(txdr->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
			return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
			/* Free old allocation, new allocation was successful */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	memset(txdr->desc, 0, txdr->size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
	txdr->next_to_use = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	txdr->next_to_clean = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
 * 				  (Descriptors) for all queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
 * Return 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	int i, err = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	for (i = 0; i < adapter->num_tx_queues; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
		if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
			e_err(probe, "Allocation for Tx Queue %u failed\n", i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
			for (i-- ; i >= 0; i--)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
				e1000_free_tx_resources(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
							&adapter->tx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
 * Configure the Tx unit of the MAC after a reset.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
static void e1000_configure_tx(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	u64 tdba;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
	u32 tdlen, tctl, tipg;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	u32 ipgr1, ipgr2;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	/* Setup the HW Tx Head and Tail descriptor pointers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	switch (adapter->num_tx_queues) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	case 1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		tdba = adapter->tx_ring[0].dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		tdlen = adapter->tx_ring[0].count *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
			sizeof(struct e1000_tx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		ew32(TDLEN, tdlen);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		ew32(TDBAH, (tdba >> 32));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		ew32(TDT, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		ew32(TDH, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	/* Set the default values for the Tx Inter Packet Gap timer */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	if ((hw->media_type == e1000_media_type_fiber ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
	     hw->media_type == e1000_media_type_internal_serdes))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	case e1000_82542_rev2_0:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	case e1000_82542_rev2_1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		tipg = DEFAULT_82542_TIPG_IPGT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	ew32(TIPG, tipg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	/* Set the Tx Interrupt Delay register */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	ew32(TIDV, adapter->tx_int_delay);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
	if (hw->mac_type >= e1000_82540)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
		ew32(TADV, adapter->tx_abs_int_delay);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	/* Program the Transmit Control Register */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	tctl = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
	tctl &= ~E1000_TCTL_CT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	e1000_config_collision_dist(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	/* Setup Transmit Descriptor Settings for eop descriptor */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
	/* only set IDE if we are delaying interrupts using the timers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
	if (adapter->tx_int_delay)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
	if (hw->mac_type < e1000_82543)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	/* Cache if we're 82544 running in PCI-X because we'll
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	 * need this to apply a workaround later in the send path. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	if (hw->mac_type == e1000_82544 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	    hw->bus_type == e1000_bus_type_pcix)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
		adapter->pcix_82544 = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	ew32(TCTL, tctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
 * Returns 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
				    struct e1000_rx_ring *rxdr)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	int size, desc_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	size = sizeof(struct e1000_buffer) * rxdr->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	rxdr->buffer_info = vzalloc(size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	if (!rxdr->buffer_info) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		e_err(probe, "Unable to allocate memory for the Rx descriptor "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
		      "ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
	desc_len = sizeof(struct e1000_rx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	/* Round up to nearest 4K */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	rxdr->size = rxdr->count * desc_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	rxdr->size = ALIGN(rxdr->size, 4096);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
					GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	if (!rxdr->desc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		e_err(probe, "Unable to allocate memory for the Rx descriptor "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		      "ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
setup_rx_desc_die:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		vfree(rxdr->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	/* Fix for errata 23, can't cross 64kB boundary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		void *olddesc = rxdr->desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		dma_addr_t olddma = rxdr->dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		e_err(rx_err, "rxdr align check failed: %u bytes at %p\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		      rxdr->size, rxdr->desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
		/* Try again, without freeing the previous */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
						&rxdr->dma, GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		/* Failed allocation, critical failure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		if (!rxdr->desc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
			e_err(probe, "Unable to allocate memory for the Rx "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
			      "descriptor ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
			goto setup_rx_desc_die;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
			/* give up */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
			dma_free_coherent(&pdev->dev, rxdr->size, rxdr->desc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
					  rxdr->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
			e_err(probe, "Unable to allocate aligned memory for "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
			      "the Rx descriptor ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
			goto setup_rx_desc_die;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
			/* Free old allocation, new allocation was successful */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	memset(rxdr->desc, 0, rxdr->size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	rxdr->next_to_clean = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	rxdr->next_to_use = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	rxdr->rx_skb_top = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
 * 				  (Descriptors) for all queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
 * Return 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
	int i, err = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	for (i = 0; i < adapter->num_rx_queues; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
			e_err(probe, "Allocation for Rx Queue %u failed\n", i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
			for (i-- ; i >= 0; i--)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
				e1000_free_rx_resources(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
							&adapter->rx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
 * e1000_setup_rctl - configure the receive control registers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
 * @adapter: Board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
static void e1000_setup_rctl(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	rctl |= E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
		E1000_RCTL_RDMTS_HALF |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
	if (hw->tbi_compatibility_on == 1)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		rctl |= E1000_RCTL_SBP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
		rctl &= ~E1000_RCTL_SBP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
		rctl &= ~E1000_RCTL_LPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		rctl |= E1000_RCTL_LPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
	/* Setup buffer sizes */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	rctl &= ~E1000_RCTL_SZ_4096;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	rctl |= E1000_RCTL_BSEX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
	switch (adapter->rx_buffer_len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		case E1000_RXBUFFER_2048:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
			rctl |= E1000_RCTL_SZ_2048;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
			rctl &= ~E1000_RCTL_BSEX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
		case E1000_RXBUFFER_4096:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
			rctl |= E1000_RCTL_SZ_4096;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
		case E1000_RXBUFFER_8192:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
			rctl |= E1000_RCTL_SZ_8192;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		case E1000_RXBUFFER_16384:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
			rctl |= E1000_RCTL_SZ_16384;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
	/* This is useful for sniffing bad packets. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	if (adapter->netdev->features & NETIF_F_RXALL) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
		/* UPE and MPE will be handled by normal PROMISC logic
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
		 * in e1000e_set_rx_mode */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
		rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
			 E1000_RCTL_BAM | /* RX All Bcast Pkts */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
			 E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
		rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
			  E1000_RCTL_DPF | /* Allow filtered pause */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
			  E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
		 * and that breaks VLANs.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
 * Configure the Rx unit of the MAC after a reset.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
static void e1000_configure_rx(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	u64 rdba;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	u32 rdlen, rctl, rxcsum;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
		rdlen = adapter->rx_ring[0].count *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		        sizeof(struct e1000_rx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		rdlen = adapter->rx_ring[0].count *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		        sizeof(struct e1000_rx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		adapter->clean_rx = e1000_clean_rx_irq;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	/* disable receives while setting up the descriptors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	/* set the Receive Delay Timer Register */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	ew32(RDTR, adapter->rx_int_delay);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	if (hw->mac_type >= e1000_82540) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
		ew32(RADV, adapter->rx_abs_int_delay);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
		if (adapter->itr_setting != 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
			ew32(ITR, 1000000000 / (adapter->itr * 256));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	 * the Base and Length of the Rx Descriptor Ring */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
	switch (adapter->num_rx_queues) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
	case 1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
		rdba = adapter->rx_ring[0].dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
		ew32(RDLEN, rdlen);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
		ew32(RDBAH, (rdba >> 32));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
		ew32(RDT, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
		ew32(RDH, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	if (hw->mac_type >= e1000_82543) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
		rxcsum = er32(RXCSUM);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
		if (adapter->rx_csum)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
			rxcsum |= E1000_RXCSUM_TUOFL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
			/* don't need to clear IPPCSE as it defaults to 0 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
			rxcsum &= ~E1000_RXCSUM_TUOFL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
		ew32(RXCSUM, rxcsum);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	/* Enable Receives */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	ew32(RCTL, rctl | E1000_RCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
 * e1000_free_tx_resources - Free Tx Resources per Queue
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
 * @tx_ring: Tx descriptor ring for a specific queue
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
 * Free all transmit software resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
				    struct e1000_tx_ring *tx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	e1000_clean_tx_ring(adapter, tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	vfree(tx_ring->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	tx_ring->buffer_info = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
			  tx_ring->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	tx_ring->desc = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
 * Free all transmit software resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	for (i = 0; i < adapter->num_tx_queues; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
					     struct e1000_buffer *buffer_info)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
	if (buffer_info->dma) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		if (buffer_info->mapped_as_page)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
				       buffer_info->length, DMA_TO_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
					 buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
					 DMA_TO_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
		buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	if (buffer_info->skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		dev_kfree_skb_any(buffer_info->skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
		buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	buffer_info->time_stamp = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	/* buffer_info must be completely set up in the transmit path */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
 * e1000_clean_tx_ring - Free Tx Buffers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
 * @tx_ring: ring to be cleaned
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
				struct e1000_tx_ring *tx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	unsigned long size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	/* Free all the Tx ring sk_buffs */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
	for (i = 0; i < tx_ring->count; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
	netdev_reset_queue(adapter->netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	size = sizeof(struct e1000_buffer) * tx_ring->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	memset(tx_ring->buffer_info, 0, size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	/* Zero out the descriptor ring */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	memset(tx_ring->desc, 0, tx_ring->size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	tx_ring->next_to_use = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	tx_ring->next_to_clean = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	tx_ring->last_tx_tso = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	writel(0, hw->hw_addr + tx_ring->tdh);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	writel(0, hw->hw_addr + tx_ring->tdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	for (i = 0; i < adapter->num_tx_queues; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
 * e1000_free_rx_resources - Free Rx Resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
 * @rx_ring: ring to clean the resources from
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
 * Free all receive software resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
				    struct e1000_rx_ring *rx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	e1000_clean_rx_ring(adapter, rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	vfree(rx_ring->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
	rx_ring->buffer_info = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
			  rx_ring->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	rx_ring->desc = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
 * Free all receive software resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	for (i = 0; i < adapter->num_rx_queues; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
 * @rx_ring: ring to free buffers from
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
				struct e1000_rx_ring *rx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	unsigned long size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	/* Free all the Rx ring sk_buffs */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
	for (i = 0; i < rx_ring->count; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
		buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		if (buffer_info->dma &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		    adapter->clean_rx == e1000_clean_rx_irq) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
			dma_unmap_single(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
			                 buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
					 DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
		} else if (buffer_info->dma &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
			dma_unmap_page(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
				       buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
				       DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
		if (buffer_info->page) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
			put_page(buffer_info->page);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
			buffer_info->page = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
		if (buffer_info->skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
			dev_kfree_skb(buffer_info->skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
			buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	/* there also may be some cached data from a chained receive */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
	if (rx_ring->rx_skb_top) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
		dev_kfree_skb(rx_ring->rx_skb_top);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
		rx_ring->rx_skb_top = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
	size = sizeof(struct e1000_buffer) * rx_ring->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	memset(rx_ring->buffer_info, 0, size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	/* Zero out the descriptor ring */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	memset(rx_ring->desc, 0, rx_ring->size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	rx_ring->next_to_clean = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	rx_ring->next_to_use = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
	writel(0, hw->hw_addr + rx_ring->rdh);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
	writel(0, hw->hw_addr + rx_ring->rdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	for (i = 0; i < adapter->num_rx_queues; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
 * and memory write and invalidate disabled for certain operations
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
	e1000_pci_clear_mwi(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
	rctl |= E1000_RCTL_RST;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
	mdelay(5);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
		e1000_clean_all_rx_rings(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	rctl &= ~E1000_RCTL_RST;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
	mdelay(5);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
		e1000_pci_set_mwi(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	if (netif_running(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
		/* No need to loop, because 82542 supports only 1 queue */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
		e1000_configure_rx(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
 * e1000_set_mac - Change the Ethernet Address of the NIC
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
 * @p: pointer to an address structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
 * Returns 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
static int e1000_set_mac(struct net_device *netdev, void *p)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	struct sockaddr *addr = p;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
	if (!is_valid_ether_addr(addr->sa_data))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
		return -EADDRNOTAVAIL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	/* 82542 2.0 needs to be in reset to write receive address registers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	if (hw->mac_type == e1000_82542_rev2_0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
		e1000_enter_82542_rst(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	e1000_rar_set(hw, hw->mac_addr, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	if (hw->mac_type == e1000_82542_rev2_0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
		e1000_leave_82542_rst(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
 * The set_rx_mode entry point is called whenever the unicast or multicast
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
 * address lists or the network interface flags are updated. This routine is
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
 * responsible for configuring the hardware for proper unicast, multicast,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
 * promiscuous mode, and all-multi behavior.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
static void e1000_set_rx_mode(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	struct netdev_hw_addr *ha;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	bool use_uc = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	u32 hash_value;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	int i, rar_entries = E1000_RAR_ENTRIES;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	if (!mcarray) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
		e_err(probe, "memory allocation failed\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
	/* Check for Promiscuous and All Multicast modes */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	if (netdev->flags & IFF_PROMISC) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		rctl &= ~E1000_RCTL_VFE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
		if (netdev->flags & IFF_ALLMULTI)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
			rctl |= E1000_RCTL_MPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
			rctl &= ~E1000_RCTL_MPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
		/* Enable VLAN filter if there is a VLAN */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
		if (e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
			rctl |= E1000_RCTL_VFE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	if (netdev_uc_count(netdev) > rar_entries - 1) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
		rctl |= E1000_RCTL_UPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
	} else if (!(netdev->flags & IFF_PROMISC)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
		rctl &= ~E1000_RCTL_UPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
		use_uc = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
	ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	/* 82542 2.0 needs to be in reset to write receive address registers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	if (hw->mac_type == e1000_82542_rev2_0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
		e1000_enter_82542_rst(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	/* load the first 14 addresses into the exact filters 1-14. Unicast
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	 * addresses take precedence to avoid disabling unicast filtering
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	 * when possible.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	 * RAR 0 is used for the station MAC address
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	 * if there are not 14 addresses, go ahead and clear the filters
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	i = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
	if (use_uc)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
		netdev_for_each_uc_addr(ha, netdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
			if (i == rar_entries)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
			e1000_rar_set(hw, ha->addr, i++);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	netdev_for_each_mc_addr(ha, netdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
		if (i == rar_entries) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
			/* load any remaining addresses into the hash table */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
			u32 hash_reg, hash_bit, mta;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
			hash_value = e1000_hash_mc_addr(hw, ha->addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
			hash_reg = (hash_value >> 5) & 0x7F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
			hash_bit = hash_value & 0x1F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
			mta = (1 << hash_bit);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
			mcarray[hash_reg] |= mta;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
			e1000_rar_set(hw, ha->addr, i++);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	for (; i < rar_entries; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
		E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
		E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	/* write the hash table completely, write from bottom to avoid
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
	 * both stupid write combining chipsets, and flushing each write */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	for (i = mta_reg_count - 1; i >= 0 ; i--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
		 * If we are on an 82544 has an errata where writing odd
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		 * offsets overwrites the previous even offset, but writing
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		 * backwards over the range solves the issue by always
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
		 * writing the odd offset first
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	if (hw->mac_type == e1000_82542_rev2_0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
		e1000_leave_82542_rst(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
	kfree(mcarray);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
 * e1000_update_phy_info_task - get phy info
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
 * @work: work struct contained inside adapter struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
 * Need to wait a few seconds after link up to get diagnostic information from
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
 * the phy
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
static void e1000_update_phy_info_task(struct work_struct *work)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	struct e1000_adapter *adapter = container_of(work,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
						     struct e1000_adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
						     phy_info_task.work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	if (test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	mutex_lock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	mutex_unlock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
 * e1000_82547_tx_fifo_stall_task - task to complete work
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
 * @work: work struct contained inside adapter struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	struct e1000_adapter *adapter = container_of(work,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
						     struct e1000_adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
						     fifo_stall_task.work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
	u32 tctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	if (test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
	mutex_lock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
	if (atomic_read(&adapter->tx_fifo_stall)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
		if ((er32(TDT) == er32(TDH)) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
		   (er32(TDFT) == er32(TDFH)) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
		   (er32(TDFTS) == er32(TDFHS))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
			tctl = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
			ew32(TDFT, adapter->tx_head_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
			ew32(TDFH, adapter->tx_head_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
			ew32(TDFTS, adapter->tx_head_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
			ew32(TDFHS, adapter->tx_head_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
			ew32(TCTL, tctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
			E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
			adapter->tx_fifo_head = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
			atomic_set(&adapter->tx_fifo_stall, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
			netif_wake_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
			schedule_delayed_work(&adapter->fifo_stall_task, 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	mutex_unlock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
bool e1000_has_link(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
	bool link_active = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
	/* get_link_status is set on LSC (link status) interrupt or rx
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
	 * sequence error interrupt (except on intel ce4100).
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
	 * get_link_status will stay false until the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
	 * e1000_check_for_link establishes link for copper adapters
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
	 * ONLY
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	switch (hw->media_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	case e1000_media_type_copper:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		if (hw->mac_type == e1000_ce4100)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
			hw->get_link_status = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
		if (hw->get_link_status) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
			e1000_check_for_link(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
			link_active = !hw->get_link_status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
			link_active = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	case e1000_media_type_fiber:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
		e1000_check_for_link(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	case e1000_media_type_internal_serdes:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
		e1000_check_for_link(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
		link_active = hw->serdes_has_link;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	return link_active;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
 * e1000_watchdog - work function
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
 * @work: work struct contained inside adapter struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
static void e1000_watchdog(struct work_struct *work)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	struct e1000_adapter *adapter = container_of(work,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
						     struct e1000_adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
						     watchdog_task.work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
	struct e1000_tx_ring *txdr = adapter->tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	u32 link, tctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	if (test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
	mutex_lock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
	link = e1000_has_link(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
	if ((netif_carrier_ok(netdev)) && link)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
		goto link_up;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
	if (link) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
		if (!netif_carrier_ok(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
			u32 ctrl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
			bool txb2b = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
			/* update snapshot of PHY registers on LSC */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
			e1000_get_speed_and_duplex(hw,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
			                           &adapter->link_speed,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
			                           &adapter->link_duplex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
			ctrl = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
			pr_info("%s NIC Link is Up %d Mbps %s, "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
				"Flow Control: %s\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
				netdev->name,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
				adapter->link_speed,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
				adapter->link_duplex == FULL_DUPLEX ?
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
				"Full Duplex" : "Half Duplex",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
				((ctrl & E1000_CTRL_TFCE) && (ctrl &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
				E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
				E1000_CTRL_RFCE) ? "RX" : ((ctrl &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
				E1000_CTRL_TFCE) ? "TX" : "None")));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
			/* adjust timeout factor according to speed/duplex */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
			adapter->tx_timeout_factor = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
			switch (adapter->link_speed) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
			case SPEED_10:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
				txb2b = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
				adapter->tx_timeout_factor = 16;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
			case SPEED_100:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
				txb2b = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
				/* maybe add some timeout factor ? */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
			/* enable transmits in the hardware */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
			tctl = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
			tctl |= E1000_TCTL_EN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
			ew32(TCTL, tctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
			netif_carrier_on(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
			if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
				schedule_delayed_work(&adapter->phy_info_task,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
						      2 * HZ);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
			adapter->smartspeed = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		if (netif_carrier_ok(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
			adapter->link_speed = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
			adapter->link_duplex = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
			pr_info("%s NIC Link is Down\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
				netdev->name);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
			netif_carrier_off(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
			if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
				schedule_delayed_work(&adapter->phy_info_task,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
						      2 * HZ);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
		e1000_smartspeed(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
link_up:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
	e1000_update_stats(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
	adapter->tpt_old = adapter->stats.tpt;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	adapter->colc_old = adapter->stats.colc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
	adapter->gorcl_old = adapter->stats.gorcl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	adapter->gotcl_old = adapter->stats.gotcl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
	e1000_update_adaptive(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	if (!netif_carrier_ok(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
			/* We've lost link, so the controller stops DMA,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
			 * but we've got queued Tx work that's never going
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
			 * to get done, so reset controller to flush Tx.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
			 * (Do the reset outside of interrupt context). */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
			adapter->tx_timeout_count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
			schedule_work(&adapter->reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
			/* exit immediately since reset is imminent */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
			goto unlock;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	/* Simple mode for Interrupt Throttle Rate (ITR) */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
		 * Symmetric Tx/Rx gets a reduced ITR=2000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
		 * Total asymmetrical Tx or Rx gets ITR=8000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
		 * everyone else is between 2000-8000.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
		u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
		u32 dif = (adapter->gotcl > adapter->gorcl ?
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
			    adapter->gotcl - adapter->gorcl :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
			    adapter->gorcl - adapter->gotcl) / 10000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
		ew32(ITR, 1000000000 / (itr * 256));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
	/* Cause software interrupt to ensure rx ring is cleaned */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
	ew32(ICS, E1000_ICS_RXDMT0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
	/* Force detection of hung controller every watchdog period */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
	adapter->detect_tx_hung = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	/* Reschedule the task */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
		schedule_delayed_work(&adapter->watchdog_task, 2 * HZ);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
unlock:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
	mutex_unlock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
enum latency_range {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
	lowest_latency = 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
	low_latency = 1,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	bulk_latency = 2,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	latency_invalid = 255
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
 * e1000_update_itr - update the dynamic ITR value based on statistics
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
 * @adapter: pointer to adapter
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
 * @itr_setting: current adapter->itr
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
 * @packets: the number of packets during this measurement interval
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
 * @bytes: the number of bytes during this measurement interval
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
 *      Stores a new ITR value based on packets and byte
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
 *      counts during the last interrupt.  The advantage of per interrupt
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
 *      computation is faster updates and more accurate ITR for the current
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
 *      traffic pattern.  Constants in this function were computed
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
 *      based on theoretical maximum wire speed and thresholds were set based
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
 *      on testing data as well as attempting to minimize response time
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
 *      while increasing bulk throughput.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
 *      this functionality is controlled by the InterruptThrottleRate module
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
 *      parameter (see e1000_param.c)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
				     u16 itr_setting, int packets, int bytes)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
	unsigned int retval = itr_setting;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	if (unlikely(hw->mac_type < e1000_82540))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
		goto update_itr_done;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	if (packets == 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		goto update_itr_done;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	switch (itr_setting) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	case lowest_latency:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
		/* jumbo frames get bulk treatment*/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
		if (bytes/packets > 8000)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
			retval = bulk_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
		else if ((packets < 5) && (bytes > 512))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
			retval = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
	case low_latency:  /* 50 usec aka 20000 ints/s */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
		if (bytes > 10000) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
			/* jumbo frames need bulk latency setting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
			if (bytes/packets > 8000)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
				retval = bulk_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
			else if ((packets < 10) || ((bytes/packets) > 1200))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
				retval = bulk_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
			else if ((packets > 35))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
				retval = lowest_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
		} else if (bytes/packets > 2000)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
			retval = bulk_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
		else if (packets <= 2 && bytes < 512)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
			retval = lowest_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	case bulk_latency: /* 250 usec aka 4000 ints/s */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
		if (bytes > 25000) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
			if (packets > 35)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
				retval = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
		} else if (bytes < 6000) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
			retval = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
update_itr_done:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
	return retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
static void e1000_set_itr(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	u16 current_itr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	u32 new_itr = adapter->itr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	if (unlikely(hw->mac_type < e1000_82540))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	if (unlikely(adapter->link_speed != SPEED_1000)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
		current_itr = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
		new_itr = 4000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
		goto set_itr_now;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
	adapter->tx_itr = e1000_update_itr(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	                            adapter->tx_itr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	                            adapter->total_tx_packets,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	                            adapter->total_tx_bytes);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		adapter->tx_itr = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
	adapter->rx_itr = e1000_update_itr(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
	                            adapter->rx_itr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
	                            adapter->total_rx_packets,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	                            adapter->total_rx_bytes);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
		adapter->rx_itr = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	switch (current_itr) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	/* counts and packets in update_itr are dependent on these numbers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
	case lowest_latency:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		new_itr = 70000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	case low_latency:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		new_itr = 20000; /* aka hwitr = ~200 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	case bulk_latency:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
		new_itr = 4000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
set_itr_now:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	if (new_itr != adapter->itr) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
		/* this attempts to bias the interrupt rate towards Bulk
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
		 * by adding intermediate steps when interrupt rate is
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
		 * increasing */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
		new_itr = new_itr > adapter->itr ?
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
		             min(adapter->itr + (new_itr >> 2), new_itr) :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		             new_itr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
		adapter->itr = new_itr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
		ew32(ITR, 1000000000 / (new_itr * 256));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
#define E1000_TX_FLAGS_CSUM		0x00000001
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
#define E1000_TX_FLAGS_VLAN		0x00000002
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
#define E1000_TX_FLAGS_TSO		0x00000004
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
#define E1000_TX_FLAGS_IPV4		0x00000008
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
#define E1000_TX_FLAGS_NO_FCS		0x00000010
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
#define E1000_TX_FLAGS_VLAN_SHIFT	16
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
static int e1000_tso(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	struct e1000_context_desc *context_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	u32 cmd_length = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
	u16 ipcse = 0, tucse, mss;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	int err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
	if (skb_is_gso(skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
		if (skb_header_cloned(skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
			if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
				return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
		mss = skb_shinfo(skb)->gso_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
		if (skb->protocol == htons(ETH_P_IP)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
			struct iphdr *iph = ip_hdr(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
			iph->tot_len = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
			iph->check = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
								 iph->daddr, 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
								 IPPROTO_TCP,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
								 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
			cmd_length = E1000_TXD_CMD_IP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
			ipcse = skb_transport_offset(skb) - 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
			ipv6_hdr(skb)->payload_len = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
			tcp_hdr(skb)->check =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
						 &ipv6_hdr(skb)->daddr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
						 0, IPPROTO_TCP, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
			ipcse = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		ipcss = skb_network_offset(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		tucss = skb_transport_offset(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
		tucse = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
		i = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
		context_desc->upper_setup.tcp_fields.tucss = tucss;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		context_desc->upper_setup.tcp_fields.tucso = tucso;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
		buffer_info->time_stamp = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
		buffer_info->next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		if (++i == tx_ring->count) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		tx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
	return false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
static bool e1000_tx_csum(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	struct e1000_context_desc *context_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
	u8 css;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	u32 cmd_len = E1000_TXD_CMD_DEXT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
	if (skb->ip_summed != CHECKSUM_PARTIAL)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		return false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
	switch (skb->protocol) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	case cpu_to_be16(ETH_P_IP):
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
			cmd_len |= E1000_TXD_CMD_TCP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
	case cpu_to_be16(ETH_P_IPV6):
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
		/* XXX not handling all IPV6 headers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
			cmd_len |= E1000_TXD_CMD_TCP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
		if (unlikely(net_ratelimit()))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
			e_warn(drv, "checksum_partial proto=%x!\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
			       skb->protocol);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	css = skb_checksum_start_offset(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
	i = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
	buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
	context_desc->lower_setup.ip_config = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
	context_desc->upper_setup.tcp_fields.tucss = css;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	context_desc->upper_setup.tcp_fields.tucso =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
		css + skb->csum_offset;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	context_desc->upper_setup.tcp_fields.tucse = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	context_desc->tcp_seg_setup.data = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
	buffer_info->time_stamp = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
	buffer_info->next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
	if (unlikely(++i == tx_ring->count)) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	tx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
#define E1000_MAX_TXD_PWR	12
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
static int e1000_tx_map(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
			struct e1000_tx_ring *tx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
			struct sk_buff *skb, unsigned int first,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
			unsigned int max_per_txd, unsigned int nr_frags,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
			unsigned int mss)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	unsigned int len = skb_headlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	unsigned int offset = 0, size, count = 0, i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
	unsigned int f, bytecount, segs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	i = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
	while (len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
		size = min(len, max_per_txd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
		/* Workaround for Controller erratum --
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
		 * descriptor for non-tso packet in a linear SKB that follows a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
		 * tso gets written back prematurely before the data is fully
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
		 * DMA'd to the controller */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
		if (!skb->data_len && tx_ring->last_tx_tso &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
		    !skb_is_gso(skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
			tx_ring->last_tx_tso = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
			size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
		/* Workaround for premature desc write-backs
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		 * in TSO mode.  Append 4-byte sentinel desc */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
		if (unlikely(mss && !nr_frags && size == len && size > 8))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
			size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
		/* work-around for errata 10 and it applies
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
		 * to all controllers in PCI-X mode
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
		 * The fix is to make sure that the first descriptor of a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		                (size > 2015) && count == 0))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		        size = 2015;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		 * terminating buffers within evenly-aligned dwords. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		if (unlikely(adapter->pcix_82544 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
		   size > 4))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
			size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
		buffer_info->length = size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
		/* set time_stamp *before* dma to help avoid a possible race */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
		buffer_info->time_stamp = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
		buffer_info->mapped_as_page = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
		buffer_info->dma = dma_map_single(&pdev->dev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
						  skb->data + offset,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
						  size,	DMA_TO_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
			goto dma_error;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
		buffer_info->next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
		len -= size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
		offset += size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
		if (len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
			i++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
			if (unlikely(i == tx_ring->count))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
				i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
	for (f = 0; f < nr_frags; f++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		const struct skb_frag_struct *frag;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		frag = &skb_shinfo(skb)->frags[f];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		len = skb_frag_size(frag);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		offset = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		while (len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
			unsigned long bufend;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
			i++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
			if (unlikely(i == tx_ring->count))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
				i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
			buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
			size = min(len, max_per_txd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
			/* Workaround for premature desc write-backs
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
			 * in TSO mode.  Append 4-byte sentinel desc */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
				size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
			/* Workaround for potential 82544 hang in PCI-X.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
			 * Avoid terminating buffers within evenly-aligned
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
			 * dwords. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
			bufend = (unsigned long)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
				page_to_phys(skb_frag_page(frag));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
			bufend += offset + size - 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
			if (unlikely(adapter->pcix_82544 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
				     !(bufend & 4) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
				     size > 4))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
				size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
			buffer_info->length = size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
			buffer_info->time_stamp = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
			buffer_info->mapped_as_page = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
			buffer_info->dma = skb_frag_dma_map(&pdev->dev, frag,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
						offset, size, DMA_TO_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
				goto dma_error;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
			buffer_info->next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
			len -= size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
			offset += size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
			count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
	segs = skb_shinfo(skb)->gso_segs ?: 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
	/* multiply data chunks by size of headers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	tx_ring->buffer_info[i].skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
	tx_ring->buffer_info[i].segs = segs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	tx_ring->buffer_info[i].bytecount = bytecount;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	tx_ring->buffer_info[first].next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
	return count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
dma_error:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	dev_err(&pdev->dev, "TX DMA map failed\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
	if (count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		count--;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
	while (count--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
		if (i==0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
			i += tx_ring->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
		i--;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
static void e1000_tx_queue(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
			   struct e1000_tx_ring *tx_ring, int tx_flags,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
			   int count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	struct e1000_tx_desc *tx_desc = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
		             E1000_TXD_CMD_TSE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
		txd_lower |= E1000_TXD_CMD_VLE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
		txd_lower &= ~(E1000_TXD_CMD_IFCS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	i = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	while (count--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
		tx_desc = E1000_TX_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
		tx_desc->lower.data =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
			cpu_to_le32(txd_lower | buffer_info->length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
		tx_desc->upper.data = cpu_to_le32(txd_upper);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
		if (unlikely(++i == tx_ring->count)) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	/* txd_cmd re-enables FCS, so we'll re-disable it here as desired. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		tx_desc->lower.data &= ~(cpu_to_le32(E1000_TXD_CMD_IFCS));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	/* Force memory writes to complete before letting h/w
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	 * know there are new descriptors to fetch.  (Only
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	 * applicable for weak-ordered memory model archs,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	 * such as IA-64). */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	wmb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
	tx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	writel(i, hw->hw_addr + tx_ring->tdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	/* we need this if more than one processor can write to our tail
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	 * at a time, it syncronizes IO on IA64/Altix systems */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	mmiowb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
/* 82547 workaround to avoid controller hang in half-duplex environment.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
 * The workaround is to avoid queuing a large packet that would span
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
 * the internal Tx FIFO ring boundary by notifying the stack to resend
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
 * to the beginning of the Tx FIFO.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
#define E1000_FIFO_HDR			0x10
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
#define E1000_82547_PAD_LEN		0x3E0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
				       struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
	if (adapter->link_duplex != HALF_DUPLEX)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
		goto no_fifo_stall_required;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
	if (atomic_read(&adapter->tx_fifo_stall))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
		return 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
		atomic_set(&adapter->tx_fifo_stall, 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		return 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
no_fifo_stall_required:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	adapter->tx_fifo_head += skb_fifo_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
	netif_stop_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	/* Herbert's original patch had:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
	 *  smp_mb__after_netif_stop_queue();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	 * but since that doesn't exist yet, just open code it. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	smp_mb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	/* We need to check again in a case another CPU has just
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
	 * made room available. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		return -EBUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	/* A reprieve! */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
	netif_start_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
	++adapter->restart_queue;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
static int e1000_maybe_stop_tx(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
                               struct e1000_tx_ring *tx_ring, int size)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
		return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	return __e1000_maybe_stop_tx(netdev, size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
				    struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
	struct e1000_tx_ring *tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	unsigned int tx_flags = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	unsigned int len = skb_headlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	unsigned int nr_frags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	unsigned int mss;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	int count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
	int tso;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	unsigned int f;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	/* This goes back to the question of how to logically map a tx queue
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	 * to a flow.  Right now, performance is impacted slightly negatively
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	 * if using multiple tx queues.  If the stack breaks away from a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
	 * single qdisc implementation, we can look at this again. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	tx_ring = adapter->tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	if (unlikely(skb->len <= 0)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
		dev_kfree_skb_any(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	/* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
	 * packets may get corrupted during padding by HW.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	 * To WA this issue, pad all small packets manually.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	if (skb->len < ETH_ZLEN) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		if (skb_pad(skb, ETH_ZLEN - skb->len))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
			return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
		skb->len = ETH_ZLEN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		skb_set_tail_pointer(skb, ETH_ZLEN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
	mss = skb_shinfo(skb)->gso_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	/* The controller does a simple calculation to
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
	 * make sure there is enough room in the FIFO before
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
	 * initiating the DMA for each buffer.  The calc is:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	 * 4 = ceil(buffer len/mss).  To make sure we don't
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
	 * overrun the FIFO, adjust the max buffer len if mss
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	 * drops. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	if (mss) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
		u8 hdr_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
		max_per_txd = min(mss << 2, max_per_txd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
		max_txd_pwr = fls(max_per_txd) - 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
		if (skb->data_len && hdr_len == len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
			switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
				unsigned int pull_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
			case e1000_82544:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
				/* Make sure we have room to chop off 4 bytes,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
				 * and that the end alignment will work out to
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
				 * this hardware's requirements
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
				 * NOTE: this is a TSO only workaround
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
				 * if end byte alignment not correct move us
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
				 * into the next dword */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
					break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
				/* fall through */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
				pull_size = min((unsigned int)4, skb->data_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
				if (!__pskb_pull_tail(skb, pull_size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
					e_err(drv, "__pskb_pull_tail "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
					      "failed.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
					dev_kfree_skb_any(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
					return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
				}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
				len = skb_headlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
			default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
				/* do nothing */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	/* reserve a descriptor for the offload context */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	/* Controller Erratum workaround */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	count += TXD_USE_COUNT(len, max_txd_pwr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	if (adapter->pcix_82544)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	/* work-around for errata 10 and it applies to all controllers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	 * in PCI-X mode, so add one more descriptor to the count
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
			(len > 2015)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	nr_frags = skb_shinfo(skb)->nr_frags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	for (f = 0; f < nr_frags; f++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
		count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
				       max_txd_pwr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	if (adapter->pcix_82544)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		count += nr_frags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	/* need: count + 2 desc gap to keep tail from touching
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	 * head, otherwise try next time */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
		return NETDEV_TX_BUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	if (unlikely((hw->mac_type == e1000_82547) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
		     (e1000_82547_fifo_workaround(adapter, skb)))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
		netif_stop_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
		if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
			schedule_delayed_work(&adapter->fifo_stall_task, 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
		return NETDEV_TX_BUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	if (vlan_tx_tag_present(skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
		tx_flags |= E1000_TX_FLAGS_VLAN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	first = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	tso = e1000_tso(adapter, tx_ring, skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	if (tso < 0) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
		dev_kfree_skb_any(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
		return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
	if (likely(tso)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
		if (likely(hw->mac_type != e1000_82544))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
			tx_ring->last_tx_tso = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
		tx_flags |= E1000_TX_FLAGS_TSO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
		tx_flags |= E1000_TX_FLAGS_CSUM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
	if (likely(skb->protocol == htons(ETH_P_IP)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
		tx_flags |= E1000_TX_FLAGS_IPV4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	if (unlikely(skb->no_fcs))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
		tx_flags |= E1000_TX_FLAGS_NO_FCS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	                     nr_frags, mss);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	if (count) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
		netdev_sent_queue(netdev, skb->len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
		skb_tx_timestamp(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
		/* Make sure there is space in the ring for the next send. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
		dev_kfree_skb_any(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
		tx_ring->buffer_info[first].time_stamp = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
		tx_ring->next_to_use = first;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
#define NUM_REGS 38 /* 1 based count */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
static void e1000_regdump(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	u32 regs[NUM_REGS];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	u32 *regs_buff = regs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	int i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	static const char * const reg_name[] = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
		"CTRL",  "STATUS",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
		"RCTL", "RDLEN", "RDH", "RDT", "RDTR",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
		"TCTL", "TDBAL", "TDBAH", "TDLEN", "TDH", "TDT",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
		"TIDV", "TXDCTL", "TADV", "TARC0",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
		"TDBAL1", "TDBAH1", "TDLEN1", "TDH1", "TDT1",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
		"TXDCTL1", "TARC1",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
		"CTRL_EXT", "ERT", "RDBAL", "RDBAH",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
		"TDFH", "TDFT", "TDFHS", "TDFTS", "TDFPC",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
		"RDFH", "RDFT", "RDFHS", "RDFTS", "RDFPC"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
	regs_buff[0]  = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	regs_buff[1]  = er32(STATUS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	regs_buff[2]  = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	regs_buff[3]  = er32(RDLEN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	regs_buff[4]  = er32(RDH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	regs_buff[5]  = er32(RDT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	regs_buff[6]  = er32(RDTR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	regs_buff[7]  = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	regs_buff[8]  = er32(TDBAL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	regs_buff[9]  = er32(TDBAH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	regs_buff[10] = er32(TDLEN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	regs_buff[11] = er32(TDH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	regs_buff[12] = er32(TDT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	regs_buff[13] = er32(TIDV);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	regs_buff[14] = er32(TXDCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	regs_buff[15] = er32(TADV);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	regs_buff[16] = er32(TARC0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
	regs_buff[17] = er32(TDBAL1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
	regs_buff[18] = er32(TDBAH1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	regs_buff[19] = er32(TDLEN1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	regs_buff[20] = er32(TDH1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
	regs_buff[21] = er32(TDT1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
	regs_buff[22] = er32(TXDCTL1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	regs_buff[23] = er32(TARC1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	regs_buff[24] = er32(CTRL_EXT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	regs_buff[25] = er32(ERT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	regs_buff[26] = er32(RDBAL0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	regs_buff[27] = er32(RDBAH0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
	regs_buff[28] = er32(TDFH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	regs_buff[29] = er32(TDFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
	regs_buff[30] = er32(TDFHS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	regs_buff[31] = er32(TDFTS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	regs_buff[32] = er32(TDFPC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	regs_buff[33] = er32(RDFH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	regs_buff[34] = er32(RDFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	regs_buff[35] = er32(RDFHS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	regs_buff[36] = er32(RDFTS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
	regs_buff[37] = er32(RDFPC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	pr_info("Register dump\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	for (i = 0; i < NUM_REGS; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
		pr_info("%-15s  %08x\n", reg_name[i], regs_buff[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
 * e1000_dump: Print registers, tx ring and rx ring
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
static void e1000_dump(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	/* this code doesn't handle multiple rings */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	struct e1000_rx_ring *rx_ring = adapter->rx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
	if (!netif_msg_hw(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
	/* Print Registers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
	e1000_regdump(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	 * transmit dump
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	pr_info("TX Desc ring0 dump\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	 * Legacy Transmit Descriptor
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	 *   +--------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	 *   +--------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	 *   +--------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	 *   63       48 47        36 35    32 31     24 23    16 15        0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	 *   63      48 47    40 39       32 31             16 15    8 7      0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
	 * Extended Data Descriptor (DTYP=0x1)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	 * 0 |                     Buffer Address [63:0]                      |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	pr_info("Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma       ] leng  ntw timestmp         bi->skb\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	pr_info("Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen] [bi->dma       ] leng  ntw timestmp         bi->skb\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	if (!netif_msg_tx_done(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
		goto rx_ring_summary;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
		struct my_u { __le64 a; __le64 b; };
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
		struct my_u *u = (struct my_u *)tx_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
		const char *type;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
			type = "NTC/U";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
		else if (i == tx_ring->next_to_use)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
			type = "NTU";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
		else if (i == tx_ring->next_to_clean)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
			type = "NTC";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
			type = "";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
		pr_info("T%c[0x%03X]    %016llX %016llX %016llX %04X  %3X %016llX %p %s\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
			((le64_to_cpu(u->b) & (1<<20)) ? 'd' : 'c'), i,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
			le64_to_cpu(u->a), le64_to_cpu(u->b),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
			(u64)buffer_info->dma, buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
			buffer_info->next_to_watch,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
			(u64)buffer_info->time_stamp, buffer_info->skb, type);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
rx_ring_summary:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	 * receive dump
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	pr_info("\nRX Desc ring dump\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
	/* Legacy Receive Descriptor Format
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	 * +-----------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	 * |                Buffer Address [63:0]                |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	 * +-----------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	 * | VLAN Tag | Errors | Status 0 | Packet csum | Length |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	 * +-----------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	 * 63       48 47    40 39      32 31         16 15      0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
	pr_info("R[desc]      [address 63:0  ] [vl er S cks ln] [bi->dma       ] [bi->skb]\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	if (!netif_msg_rx_status(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
		goto exit;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
		struct e1000_buffer *buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		struct my_u { __le64 a; __le64 b; };
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
		struct my_u *u = (struct my_u *)rx_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
		const char *type;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		if (i == rx_ring->next_to_use)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
			type = "NTU";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		else if (i == rx_ring->next_to_clean)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
			type = "NTC";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
			type = "";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		pr_info("R[0x%03X]     %016llX %016llX %016llX %p %s\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
			i, le64_to_cpu(u->a), le64_to_cpu(u->b),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
			(u64)buffer_info->dma, buffer_info->skb, type);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	} /* for */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
	/* dump the descriptor caches */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	/* rx */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	pr_info("Rx descriptor cache in 64bit format\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	for (i = 0x6000; i <= 0x63FF ; i += 0x10) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
		pr_info("R%04X: %08X|%08X %08X|%08X\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
			i,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
			readl(adapter->hw.hw_addr + i+4),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
			readl(adapter->hw.hw_addr + i),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
			readl(adapter->hw.hw_addr + i+12),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
			readl(adapter->hw.hw_addr + i+8));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	/* tx */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	pr_info("Tx descriptor cache in 64bit format\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	for (i = 0x7000; i <= 0x73FF ; i += 0x10) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
		pr_info("T%04X: %08X|%08X %08X|%08X\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
			i,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
			readl(adapter->hw.hw_addr + i+4),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
			readl(adapter->hw.hw_addr + i),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
			readl(adapter->hw.hw_addr + i+12),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
			readl(adapter->hw.hw_addr + i+8));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
exit:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
 * e1000_tx_timeout - Respond to a Tx Hang
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
static void e1000_tx_timeout(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
	/* Do the reset outside of interrupt context */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	adapter->tx_timeout_count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
	schedule_work(&adapter->reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
static void e1000_reset_task(struct work_struct *work)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
	struct e1000_adapter *adapter =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
		container_of(work, struct e1000_adapter, reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
	if (test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	e_err(drv, "Reset adapter\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	e1000_reinit_safe(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
 * e1000_get_stats - Get System Network Statistics
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
 * Returns the address of the device statistics structure.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
 * The statistics are actually updated from the watchdog.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
	/* only return the current stats */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
	return &netdev->stats;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
 * e1000_change_mtu - Change the Maximum Transfer Unit
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
 * @new_mtu: new value for maximum frame size
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
 * Returns 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
		e_err(probe, "Invalid MTU setting\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		return -EINVAL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
	/* Adapter-specific max frame size limits. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	case e1000_undefined ... e1000_82542_rev2_1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
			e_err(probe, "Jumbo Frames not supported.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
			return -EINVAL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
		msleep(1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	/* e1000_down has a dependency on max_frame_size */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
	hw->max_frame_size = max_frame;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
		e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	 * means we reserve 2 more, this pushes us to allocate from the next
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	 * larger slab size.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	 * i.e. RXBUFFER_2048 --> size-4096 slab
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
	 *  fragmented skbs */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
	if (max_frame <= E1000_RXBUFFER_2048)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
		adapter->rx_buffer_len = PAGE_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	/* adjust allocation if LPE protects us, and we aren't using SBP */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	if (!hw->tbi_compatibility_on &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
	pr_info("%s changing MTU from %d to %d\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
		netdev->name, netdev->mtu, new_mtu);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	netdev->mtu = new_mtu;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
		e1000_up(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
		e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	clear_bit(__E1000_RESETTING, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
 * e1000_update_stats - Update the board statistics counters
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
void e1000_update_stats(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
	unsigned long flags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	u16 phy_tmp;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	 * Prevent stats update while adapter is being reset, or if the pci
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
	 * connection is down.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	if (adapter->link_speed == 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	if (pci_channel_offline(pdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	spin_lock_irqsave(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	/* these counters are modified from e1000_tbi_adjust_stats,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	 * called from the interrupt context, so they must only
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	 * be written while holding adapter->stats_lock
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	adapter->stats.crcerrs += er32(CRCERRS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
	adapter->stats.gprc += er32(GPRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
	adapter->stats.gorcl += er32(GORCL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
	adapter->stats.gorch += er32(GORCH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
	adapter->stats.bprc += er32(BPRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
	adapter->stats.mprc += er32(MPRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
	adapter->stats.roc += er32(ROC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
	adapter->stats.prc64 += er32(PRC64);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
	adapter->stats.prc127 += er32(PRC127);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	adapter->stats.prc255 += er32(PRC255);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
	adapter->stats.prc511 += er32(PRC511);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
	adapter->stats.prc1023 += er32(PRC1023);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	adapter->stats.prc1522 += er32(PRC1522);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
	adapter->stats.symerrs += er32(SYMERRS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
	adapter->stats.mpc += er32(MPC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
	adapter->stats.scc += er32(SCC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
	adapter->stats.ecol += er32(ECOL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
	adapter->stats.mcc += er32(MCC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	adapter->stats.latecol += er32(LATECOL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
	adapter->stats.dc += er32(DC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
	adapter->stats.sec += er32(SEC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
	adapter->stats.rlec += er32(RLEC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
	adapter->stats.xonrxc += er32(XONRXC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
	adapter->stats.xontxc += er32(XONTXC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
	adapter->stats.xoffrxc += er32(XOFFRXC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	adapter->stats.xofftxc += er32(XOFFTXC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	adapter->stats.fcruc += er32(FCRUC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	adapter->stats.gptc += er32(GPTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
	adapter->stats.gotcl += er32(GOTCL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
	adapter->stats.gotch += er32(GOTCH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	adapter->stats.rnbc += er32(RNBC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
	adapter->stats.ruc += er32(RUC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
	adapter->stats.rfc += er32(RFC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
	adapter->stats.rjc += er32(RJC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
	adapter->stats.torl += er32(TORL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
	adapter->stats.torh += er32(TORH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
	adapter->stats.totl += er32(TOTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
	adapter->stats.toth += er32(TOTH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	adapter->stats.tpr += er32(TPR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
	adapter->stats.ptc64 += er32(PTC64);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
	adapter->stats.ptc127 += er32(PTC127);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
	adapter->stats.ptc255 += er32(PTC255);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	adapter->stats.ptc511 += er32(PTC511);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
	adapter->stats.ptc1023 += er32(PTC1023);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	adapter->stats.ptc1522 += er32(PTC1522);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
	adapter->stats.mptc += er32(MPTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	adapter->stats.bptc += er32(BPTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
	/* used for adaptive IFS */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
	hw->tx_packet_delta = er32(TPT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
	adapter->stats.tpt += hw->tx_packet_delta;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	hw->collision_delta = er32(COLC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
	adapter->stats.colc += hw->collision_delta;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
	if (hw->mac_type >= e1000_82543) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
		adapter->stats.algnerrc += er32(ALGNERRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
		adapter->stats.rxerrc += er32(RXERRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
		adapter->stats.tncrs += er32(TNCRS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
		adapter->stats.cexterr += er32(CEXTERR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
		adapter->stats.tsctc += er32(TSCTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
		adapter->stats.tsctfc += er32(TSCTFC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
	/* Fill out the OS statistics structure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
	netdev->stats.multicast = adapter->stats.mprc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
	netdev->stats.collisions = adapter->stats.colc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
	/* Rx Errors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
	/* RLEC on some newer hardware can be incorrect so build
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
	* our own version based on RUC and ROC */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	netdev->stats.rx_errors = adapter->stats.rxerrc +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
		adapter->stats.crcerrs + adapter->stats.algnerrc +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
		adapter->stats.ruc + adapter->stats.roc +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
		adapter->stats.cexterr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	/* Tx Errors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
	netdev->stats.tx_errors = adapter->stats.txerrc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
	netdev->stats.tx_window_errors = adapter->stats.latecol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
	if (hw->bad_tx_carr_stats_fd &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
	    adapter->link_duplex == FULL_DUPLEX) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		netdev->stats.tx_carrier_errors = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		adapter->stats.tncrs = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
	/* Tx Dropped needs to be maintained elsewhere */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
	/* Phy Stats */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	if (hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		if ((adapter->link_speed == SPEED_1000) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
			adapter->phy_stats.idle_errors += phy_tmp;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		if ((hw->mac_type <= e1000_82546) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
		   (hw->phy_type == e1000_phy_m88) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
			adapter->phy_stats.receive_errors += phy_tmp;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
	/* Management Stats */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
	if (hw->has_smbus) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
		adapter->stats.mgptc += er32(MGTPTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
		adapter->stats.mgprc += er32(MGTPRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
		adapter->stats.mgpdc += er32(MGTPDC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
	spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
 * e1000_intr - Interrupt Handler
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
 * @irq: interrupt number
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
 * @data: pointer to a network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
static irqreturn_t e1000_intr(int irq, void *data)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	struct net_device *netdev = data;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	u32 icr = er32(ICR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	if (unlikely((!icr)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
		return IRQ_NONE;  /* Not our interrupt */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
	 * we might have caused the interrupt, but the above
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
	 * read cleared it, and just in case the driver is
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
	 * down there is nothing to do so return handled
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
	if (unlikely(test_bit(__E1000_DOWN, &adapter->flags)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		return IRQ_HANDLED;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		hw->get_link_status = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
		/* guard against interrupt when we're going down */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
		if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
			schedule_delayed_work(&adapter->watchdog_task, 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
	/* disable interrupts, without the synchronize_irq bit */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
	ew32(IMC, ~0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
	if (likely(napi_schedule_prep(&adapter->napi))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
		adapter->total_tx_bytes = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		adapter->total_tx_packets = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
		adapter->total_rx_bytes = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
		adapter->total_rx_packets = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
		__napi_schedule(&adapter->napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		/* this really should not happen! if it does it is basically a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
		 * bug, but not a hard error, so enable ints and continue */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
		if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
			e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	return IRQ_HANDLED;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
 * e1000_clean - NAPI Rx polling callback
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
static int e1000_clean(struct napi_struct *napi, int budget)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
	int tx_clean_complete = 0, work_done = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	if (!tx_clean_complete)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
		work_done = budget;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	/* If budget not fully consumed, exit the polling mode */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
	if (work_done < budget) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
		if (likely(adapter->itr_setting & 3))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
			e1000_set_itr(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
		napi_complete(napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
		if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
			e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
	return work_done;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
			       struct e1000_tx_ring *tx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
	struct e1000_tx_desc *tx_desc, *eop_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
	unsigned int i, eop;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
	unsigned int count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	unsigned int total_tx_bytes=0, total_tx_packets=0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
	unsigned int bytes_compl = 0, pkts_compl = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
	i = tx_ring->next_to_clean;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	eop = tx_ring->buffer_info[i].next_to_watch;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	       (count < tx_ring->count)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
		bool cleaned = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
		rmb();	/* read buffer_info after eop_desc */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		for ( ; !cleaned; count++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
			tx_desc = E1000_TX_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
			buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
			cleaned = (i == eop);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
			if (cleaned) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
				total_tx_packets += buffer_info->segs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
				total_tx_bytes += buffer_info->bytecount;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
				if (buffer_info->skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
					bytes_compl += buffer_info->skb->len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
					pkts_compl++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
				}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
			tx_desc->upper.data = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
			if (unlikely(++i == tx_ring->count)) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
		eop = tx_ring->buffer_info[i].next_to_watch;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	tx_ring->next_to_clean = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
	netdev_completed_queue(netdev, pkts_compl, bytes_compl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
#define TX_WAKE_THRESHOLD 32
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	if (unlikely(count && netif_carrier_ok(netdev) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		/* Make sure that anybody stopping the queue after this
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
		 * sees the new next_to_clean.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
		smp_mb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
		if (netif_queue_stopped(netdev) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
			netif_wake_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
			++adapter->restart_queue;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
	if (adapter->detect_tx_hung) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		/* Detect a transmit hang in hardware, this serializes the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
		 * check with the clearing of time_stamp and movement of i */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
		adapter->detect_tx_hung = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
		if (tx_ring->buffer_info[eop].time_stamp &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
		               (adapter->tx_timeout_factor * HZ)) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
			/* detected Tx unit hang */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
			e_err(drv, "Detected Tx Unit Hang\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
			      "  Tx Queue             <%lu>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
			      "  TDH                  <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
			      "  TDT                  <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
			      "  next_to_use          <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
			      "  next_to_clean        <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
			      "buffer_info[next_to_clean]\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
			      "  time_stamp           <%lx>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
			      "  next_to_watch        <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
			      "  jiffies              <%lx>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
			      "  next_to_watch.status <%x>\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
				(unsigned long)((tx_ring - adapter->tx_ring) /
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
					sizeof(struct e1000_tx_ring)),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
				readl(hw->hw_addr + tx_ring->tdh),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
				readl(hw->hw_addr + tx_ring->tdt),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
				tx_ring->next_to_use,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
				tx_ring->next_to_clean,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
				tx_ring->buffer_info[eop].time_stamp,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
				eop,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
				jiffies,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
				eop_desc->upper.fields.status);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
			e1000_dump(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
			netif_stop_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
	adapter->total_tx_bytes += total_tx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
	adapter->total_tx_packets += total_tx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
	netdev->stats.tx_bytes += total_tx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
	netdev->stats.tx_packets += total_tx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
	return count < tx_ring->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
 * e1000_rx_checksum - Receive Checksum Offload for 82543
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
 * @adapter:     board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
 * @status_err:  receive descriptor status and error fields
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
 * @csum:        receive descriptor csum field
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
 * @sk_buff:     socket buffer with received data
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
			      u32 csum, struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
	u16 status = (u16)status_err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
	u8 errors = (u8)(status_err >> 24);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
	skb_checksum_none_assert(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
	/* 82543 or newer only */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	if (unlikely(hw->mac_type < e1000_82543)) return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
	/* Ignore Checksum bit is set */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
	/* TCP/UDP checksum error bit is set */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
		/* let the stack verify checksum errors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
		adapter->hw_csum_err++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
	/* TCP/UDP Checksum has not been calculated */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
	if (!(status & E1000_RXD_STAT_TCPCS))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
	/* It must be a TCP or UDP packet with a valid checksum */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
		/* TCP checksum is good */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
		skb->ip_summed = CHECKSUM_UNNECESSARY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	adapter->hw_csum_good++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
 * e1000_consume_page - helper function
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
                               u16 length)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
	bi->page = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
	skb->len += length;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
	skb->data_len += length;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
	skb->truesize += PAGE_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
 * e1000_receive_skb - helper function to handle rx indications
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
 * @status: descriptor status field as written by hardware
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
 * @skb: pointer to sk_buff to be indicated to stack
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
			      __le16 vlan, struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
	skb->protocol = eth_type_trans(skb, adapter->netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
	if (status & E1000_RXD_STAT_VP) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
		u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		__vlan_hwaccel_put_tag(skb, vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
	napi_gro_receive(&adapter->napi, skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
 * @rx_ring: ring to clean
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
 * @work_done: amount of napi work completed this call
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
 * @work_to_do: max amount of work allowed for this call to do
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
 * the return value indicates whether actual cleaning was done, there
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
 * is no guarantee that everything was cleaned
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
				     struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
				     int *work_done, int work_to_do)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
	struct e1000_rx_desc *rx_desc, *next_rxd;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
	struct e1000_buffer *buffer_info, *next_buffer;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
	unsigned long irq_flags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
	u32 length;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
	int cleaned_count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
	bool cleaned = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
	unsigned int total_rx_bytes=0, total_rx_packets=0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
	i = rx_ring->next_to_clean;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
	rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
	buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	while (rx_desc->status & E1000_RXD_STAT_DD) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		struct sk_buff *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
		u8 status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		if (*work_done >= work_to_do)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
		(*work_done)++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
		rmb(); /* read descriptor and rx_buffer_info after status DD */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
		status = rx_desc->status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
		skb = buffer_info->skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
		buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
		if (++i == rx_ring->count) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
		next_rxd = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
		prefetch(next_rxd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
		next_buffer = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
		cleaned = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
		cleaned_count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
		dma_unmap_page(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
			       buffer_info->length, DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
		buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
		length = le16_to_cpu(rx_desc->length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
		/* errors is only valid for DD + EOP descriptors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
		if (unlikely((status & E1000_RXD_STAT_EOP) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
			u8 *mapped;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
			u8 last_byte;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
			mapped = page_address(buffer_info->page);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
			last_byte = *(mapped + length - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
				       last_byte)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
				spin_lock_irqsave(&adapter->stats_lock,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
				                  irq_flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
				e1000_tbi_adjust_stats(hw, &adapter->stats,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
						       length, mapped);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
				spin_unlock_irqrestore(&adapter->stats_lock,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
				                       irq_flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
				length--;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
			} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
				if (netdev->features & NETIF_F_RXALL)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
					goto process_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
				/* recycle both page and skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
				buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
				/* an error means any chain goes out the window
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
				 * too */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
				if (rx_ring->rx_skb_top)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
					dev_kfree_skb(rx_ring->rx_skb_top);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
				rx_ring->rx_skb_top = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
				goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
#define rxtop rx_ring->rx_skb_top
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
process_skb:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
		if (!(status & E1000_RXD_STAT_EOP)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
			/* this descriptor is only the beginning (or middle) */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
			if (!rxtop) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
				/* this is the beginning of a chain */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
				rxtop = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
				                   0, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
			} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
				/* this is the middle of a chain */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
				skb_fill_page_desc(rxtop,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
				    skb_shinfo(rxtop)->nr_frags,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
				    buffer_info->page, 0, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
				/* re-use the skb, only consumed the page */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
				buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
			e1000_consume_page(buffer_info, rxtop, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
			goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
			if (rxtop) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
				/* end of the chain */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
				skb_fill_page_desc(rxtop,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
				    skb_shinfo(rxtop)->nr_frags,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
				    buffer_info->page, 0, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
				/* re-use the current skb, we only consumed the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
				 * page */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
				buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
				skb = rxtop;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
				rxtop = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
				e1000_consume_page(buffer_info, skb, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
			} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
				/* no chain, got EOP, this buf is the packet
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
				 * copybreak to save the put_page/alloc_page */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
				if (length <= copybreak &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
				    skb_tailroom(skb) >= length) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
					u8 *vaddr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
					vaddr = kmap_atomic(buffer_info->page);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
					memcpy(skb_tail_pointer(skb), vaddr, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
					kunmap_atomic(vaddr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
					/* re-use the page, so don't erase
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
					 * buffer_info->page */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
					skb_put(skb, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
				} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
					skb_fill_page_desc(skb, 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
					                   buffer_info->page, 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
				                           length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
					e1000_consume_page(buffer_info, skb,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
					                   length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
				}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
		e1000_rx_checksum(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		                  (u32)(status) |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		                  ((u32)(rx_desc->errors) << 24),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
		                  le16_to_cpu(rx_desc->csum), skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
		total_rx_bytes += (skb->len - 4); /* don't count FCS */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		if (likely(!(netdev->features & NETIF_F_RXFCS)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
			pskb_trim(skb, skb->len - 4);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
		total_rx_packets++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
		/* eth type trans needs skb->data to point to something */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
		if (!pskb_may_pull(skb, ETH_HLEN)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
			e_err(drv, "pskb_may_pull failed.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
			dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
			goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
next_desc:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
		rx_desc->status = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
		/* return some buffers to hardware, one at a time is too slow */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
			cleaned_count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
		/* use prefetched values */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
		rx_desc = next_rxd;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
		buffer_info = next_buffer;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
	rx_ring->next_to_clean = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
	if (cleaned_count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	adapter->total_rx_packets += total_rx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
	adapter->total_rx_bytes += total_rx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	netdev->stats.rx_bytes += total_rx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
	netdev->stats.rx_packets += total_rx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	return cleaned;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
 * this should improve performance for small packets with large amounts
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
 * of reassembly being done in the stack
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
static void e1000_check_copybreak(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
				 struct e1000_buffer *buffer_info,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
				 u32 length, struct sk_buff **skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	struct sk_buff *new_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
	if (length > copybreak)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
	new_skb = netdev_alloc_skb_ip_align(netdev, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
	if (!new_skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
	skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
				       (*skb)->data - NET_IP_ALIGN,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
				       length + NET_IP_ALIGN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
	/* save the skb in buffer_info as good */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
	buffer_info->skb = *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
	*skb = new_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
 * @rx_ring: ring to clean
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
 * @work_done: amount of napi work completed this call
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
 * @work_to_do: max amount of work allowed for this call to do
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
			       struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
			       int *work_done, int work_to_do)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
	struct e1000_rx_desc *rx_desc, *next_rxd;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
	struct e1000_buffer *buffer_info, *next_buffer;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
	unsigned long flags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
	u32 length;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
	int cleaned_count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
	bool cleaned = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	unsigned int total_rx_bytes=0, total_rx_packets=0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	i = rx_ring->next_to_clean;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
	rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	while (rx_desc->status & E1000_RXD_STAT_DD) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
		struct sk_buff *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
		u8 status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
		if (*work_done >= work_to_do)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
		(*work_done)++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
		rmb(); /* read descriptor and rx_buffer_info after status DD */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
		status = rx_desc->status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
		skb = buffer_info->skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
		buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
		prefetch(skb->data - NET_IP_ALIGN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
		if (++i == rx_ring->count) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
		next_rxd = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
		prefetch(next_rxd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
		next_buffer = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		cleaned = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
		cleaned_count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
		dma_unmap_single(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
				 buffer_info->length, DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
		length = le16_to_cpu(rx_desc->length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
		/* !EOP means multiple descriptors were used to store a single
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		 * packet, if thats the case we need to toss it.  In fact, we
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
		 * to toss every packet with the EOP bit clear and the next
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		 * frame that _does_ have the EOP bit set, as it is by
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
		 * definition only a frame fragment
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
			adapter->discarding = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
		if (adapter->discarding) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
			/* All receives must fit into a single buffer */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
			e_dbg("Receive packet consumed multiple buffers\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
			/* recycle */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
			buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
			if (status & E1000_RXD_STAT_EOP)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
				adapter->discarding = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
			goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
			u8 last_byte = *(skb->data + length - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
				       last_byte)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
				spin_lock_irqsave(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
				e1000_tbi_adjust_stats(hw, &adapter->stats,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
				                       length, skb->data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
				spin_unlock_irqrestore(&adapter->stats_lock,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
				                       flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
				length--;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
			} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
				if (netdev->features & NETIF_F_RXALL)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
					goto process_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
				/* recycle */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
				buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
				goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
process_skb:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
		total_rx_bytes += (length - 4); /* don't count FCS */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
		total_rx_packets++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
		if (likely(!(netdev->features & NETIF_F_RXFCS)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
			/* adjust length to remove Ethernet CRC, this must be
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
			 * done after the TBI_ACCEPT workaround above
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
			 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
			length -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		e1000_check_copybreak(netdev, buffer_info, length, &skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
		skb_put(skb, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
		/* Receive Checksum Offload */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
		e1000_rx_checksum(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
				  (u32)(status) |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
				  ((u32)(rx_desc->errors) << 24),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
				  le16_to_cpu(rx_desc->csum), skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
next_desc:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
		rx_desc->status = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
		/* return some buffers to hardware, one at a time is too slow */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
			cleaned_count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
		/* use prefetched values */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
		rx_desc = next_rxd;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
		buffer_info = next_buffer;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
	rx_ring->next_to_clean = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
	if (cleaned_count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
	adapter->total_rx_packets += total_rx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
	adapter->total_rx_bytes += total_rx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
	netdev->stats.rx_bytes += total_rx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
	netdev->stats.rx_packets += total_rx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	return cleaned;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
 * @adapter: address of board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
 * @rx_ring: pointer to receive ring structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
 * @cleaned_count: number of buffers to allocate this pass
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
static void
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
                             struct e1000_rx_ring *rx_ring, int cleaned_count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
	struct e1000_rx_desc *rx_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
	struct sk_buff *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	unsigned int bufsz = 256 - 16 /*for skb_reserve */ ;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
	i = rx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	while (cleaned_count--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
		skb = buffer_info->skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
		if (skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
			skb_trim(skb, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
			goto check_page;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
		if (unlikely(!skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
			/* Better luck next round */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
			adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
		buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
		buffer_info->length = adapter->rx_buffer_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
check_page:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
		/* allocate a new page if necessary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
		if (!buffer_info->page) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
			buffer_info->page = alloc_page(GFP_ATOMIC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
			if (unlikely(!buffer_info->page)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
				adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
		if (!buffer_info->dma) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
			buffer_info->dma = dma_map_page(&pdev->dev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
			                                buffer_info->page, 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
							buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
							DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
				put_page(buffer_info->page);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
				dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
				buffer_info->page = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
				buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
				buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
				adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
				break; /* while !buffer_info->skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
		rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
		if (unlikely(++i == rx_ring->count))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
			i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
		buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	if (likely(rx_ring->next_to_use != i)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
		rx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
		if (unlikely(i-- == 0))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
			i = (rx_ring->count - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		/* Force memory writes to complete before letting h/w
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
		 * know there are new descriptors to fetch.  (Only
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
		 * applicable for weak-ordered memory model archs,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
		 * such as IA-64). */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
		wmb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
 * @adapter: address of board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
				   struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
				   int cleaned_count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
	struct e1000_rx_desc *rx_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	struct sk_buff *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	unsigned int bufsz = adapter->rx_buffer_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	i = rx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
	buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
	while (cleaned_count--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
		skb = buffer_info->skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
		if (skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
			skb_trim(skb, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
			goto map_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
		if (unlikely(!skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
			/* Better luck next round */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
			adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		/* Fix for errata 23, can't cross 64kB boundary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
			struct sk_buff *oldskb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
			e_err(rx_err, "skb align check failed: %u bytes at "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
			      "%p\n", bufsz, skb->data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
			/* Try again, without freeing the previous */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
			/* Failed allocation, critical failure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
			if (!skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
				dev_kfree_skb(oldskb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
				adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
				/* give up */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
				dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
				dev_kfree_skb(oldskb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
				adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
				break; /* while !buffer_info->skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
			/* Use new allocation */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
			dev_kfree_skb(oldskb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
		buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
		buffer_info->length = adapter->rx_buffer_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
map_skb:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		buffer_info->dma = dma_map_single(&pdev->dev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
						  skb->data,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
						  buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
						  DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
			dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
			buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
			buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
			adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
			break; /* while !buffer_info->skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
		 * XXX if it was allocated cleanly it will never map to a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
		 * boundary crossing
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
		/* Fix for errata 23, can't cross 64kB boundary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
		if (!e1000_check_64k_bound(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
					(void *)(unsigned long)buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
					adapter->rx_buffer_len)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
			e_err(rx_err, "dma align check failed: %u bytes at "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
			      "%p\n", adapter->rx_buffer_len,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
			      (void *)(unsigned long)buffer_info->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
			dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
			buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
			dma_unmap_single(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
					 adapter->rx_buffer_len,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
					 DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
			buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
			adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
			break; /* while !buffer_info->skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
		rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
		if (unlikely(++i == rx_ring->count))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
			i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
		buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	if (likely(rx_ring->next_to_use != i)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
		rx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
		if (unlikely(i-- == 0))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
			i = (rx_ring->count - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		/* Force memory writes to complete before letting h/w
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
		 * know there are new descriptors to fetch.  (Only
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		 * applicable for weak-ordered memory model archs,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
		 * such as IA-64). */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
		wmb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
		writel(i, hw->hw_addr + rx_ring->rdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
 * @adapter:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
static void e1000_smartspeed(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
	u16 phy_status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
	u16 phy_ctrl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	if (adapter->smartspeed == 0) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
		/* If Master/Slave config fault is asserted twice,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
		 * we assume back-to-back */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
					    phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
			adapter->smartspeed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
			if (!e1000_phy_setup_autoneg(hw) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
			   !e1000_read_phy_reg(hw, PHY_CTRL,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
				   	       &phy_ctrl)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
					     MII_CR_RESTART_AUTO_NEG);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
				e1000_write_phy_reg(hw, PHY_CTRL,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
						    phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
		/* If still no link, perhaps using 2/3 pair cable */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
		phy_ctrl |= CR_1000T_MS_ENABLE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
		if (!e1000_phy_setup_autoneg(hw) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
				     MII_CR_RESTART_AUTO_NEG);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
		adapter->smartspeed = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
 * e1000_ioctl -
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
 * @netdev:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
 * @ifreq:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
 * @cmd:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	switch (cmd) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	case SIOCGMIIPHY:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
	case SIOCGMIIREG:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	case SIOCSMIIREG:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
		return e1000_mii_ioctl(netdev, ifr, cmd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
		return -EOPNOTSUPP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
 * e1000_mii_ioctl -
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
 * @netdev:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
 * @ifreq:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
 * @cmd:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
			   int cmd)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
	struct mii_ioctl_data *data = if_mii(ifr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	int retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
	u16 mii_reg;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
	unsigned long flags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
	if (hw->media_type != e1000_media_type_copper)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
		return -EOPNOTSUPP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	switch (cmd) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
	case SIOCGMIIPHY:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
		data->phy_id = hw->phy_addr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	case SIOCGMIIREG:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
		spin_lock_irqsave(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
				   &data->val_out)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
			return -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
	case SIOCSMIIREG:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
		if (data->reg_num & ~(0x1F))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
			return -EFAULT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
		mii_reg = data->val_in;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
		spin_lock_irqsave(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
		if (e1000_write_phy_reg(hw, data->reg_num,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
					mii_reg)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
			return -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
		if (hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
			switch (data->reg_num) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
			case PHY_CTRL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
				if (mii_reg & MII_CR_POWER_DOWN)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
					break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
					hw->autoneg = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
					hw->autoneg_advertised = 0x2F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
				} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
					u32 speed;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
					if (mii_reg & 0x40)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
						speed = SPEED_1000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
					else if (mii_reg & 0x2000)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
						speed = SPEED_100;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
					else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
						speed = SPEED_10;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
					retval = e1000_set_spd_dplx(
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
						adapter, speed,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
						((mii_reg & 0x100)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
						 ? DUPLEX_FULL :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
						 DUPLEX_HALF));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
					if (retval)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
						return retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
				}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
				if (netif_running(adapter->netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
					e1000_reinit_locked(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
				else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
					e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
			case M88E1000_PHY_SPEC_CTRL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
			case M88E1000_EXT_PHY_SPEC_CTRL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
				if (e1000_phy_reset(hw))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
					return -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
			switch (data->reg_num) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
			case PHY_CTRL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
				if (mii_reg & MII_CR_POWER_DOWN)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
					break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
				if (netif_running(adapter->netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
					e1000_reinit_locked(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
				else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
					e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
		return -EOPNOTSUPP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
	return E1000_SUCCESS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
void e1000_pci_set_mwi(struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	int ret_val = pci_set_mwi(adapter->pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	if (ret_val)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
		e_err(probe, "Error in setting MWI\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
void e1000_pci_clear_mwi(struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
	pci_clear_mwi(adapter->pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
	return pcix_get_mmrbc(adapter->pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	pcix_set_mmrbc(adapter->pdev, mmrbc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
	outl(value, port);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
static bool e1000_vlan_used(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
	u16 vid;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
		return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
	return false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
static void __e1000_vlan_mode(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
			      netdev_features_t features)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
	u32 ctrl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
	ctrl = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
	if (features & NETIF_F_HW_VLAN_RX) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
		/* enable VLAN tag insert/strip */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
		ctrl |= E1000_CTRL_VME;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
		/* disable VLAN tag insert/strip */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
		ctrl &= ~E1000_CTRL_VME;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
	ew32(CTRL, ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
				     bool filter_on)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
		e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
	__e1000_vlan_mode(adapter, adapter->netdev->features);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	if (filter_on) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
		/* enable VLAN receive filtering */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
		rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
		rctl &= ~E1000_RCTL_CFIEN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
		if (!(adapter->netdev->flags & IFF_PROMISC))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
			rctl |= E1000_RCTL_VFE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
		ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
		e1000_update_mng_vlan(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
		/* disable VLAN receive filtering */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
		rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
		rctl &= ~E1000_RCTL_VFE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
		ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
		e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
static void e1000_vlan_mode(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
			    netdev_features_t features)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
		e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
	__e1000_vlan_mode(adapter, features);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
		e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
	u32 vfta, index;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
	if ((hw->mng_cookie.status &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
	    (vid == adapter->mng_vlan_id))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
		return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
	if (!e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
		e1000_vlan_filter_on_off(adapter, true);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
	/* add VID to filter table */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
	index = (vid >> 5) & 0x7F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
	vfta |= (1 << (vid & 0x1F));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
	e1000_write_vfta(hw, index, vfta);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
	set_bit(vid, adapter->active_vlans);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
	u32 vfta, index;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
		e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
		e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
	/* remove VID from filter table */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
	index = (vid >> 5) & 0x7F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
	vfta &= ~(1 << (vid & 0x1F));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
	e1000_write_vfta(hw, index, vfta);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
	clear_bit(vid, adapter->active_vlans);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
	if (!e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
		e1000_vlan_filter_on_off(adapter, false);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
static void e1000_restore_vlan(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
	u16 vid;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
	if (!e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
	e1000_vlan_filter_on_off(adapter, true);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
		e1000_vlan_rx_add_vid(adapter->netdev, vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
	hw->autoneg = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
	/* Make sure dplx is at most 1 bit and lsb of speed is not set
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
	 * for the switch() below to work */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
	if ((spd & 1) || (dplx & ~1))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
		goto err_inval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
	/* Fiber NICs only allow 1000 gbps Full duplex */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
	if ((hw->media_type == e1000_media_type_fiber) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
	    spd != SPEED_1000 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
	    dplx != DUPLEX_FULL)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
		goto err_inval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
	switch (spd + dplx) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
	case SPEED_10 + DUPLEX_HALF:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
		hw->forced_speed_duplex = e1000_10_half;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	case SPEED_10 + DUPLEX_FULL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
		hw->forced_speed_duplex = e1000_10_full;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
	case SPEED_100 + DUPLEX_HALF:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
		hw->forced_speed_duplex = e1000_100_half;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
	case SPEED_100 + DUPLEX_FULL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
		hw->forced_speed_duplex = e1000_100_full;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
	case SPEED_1000 + DUPLEX_FULL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
		hw->autoneg = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
		goto err_inval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
	/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
	hw->mdix = AUTO_ALL_MODES;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
err_inval:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
	e_err(probe, "Unsupported Speed/Duplex configuration\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
	return -EINVAL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
	u32 ctrl, ctrl_ext, rctl, status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
	u32 wufc = adapter->wol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
	int retval = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
	netif_device_detach(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
	if (netif_running(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
		e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
	retval = pci_save_state(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
	if (retval)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
		return retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
	status = er32(STATUS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
	if (status & E1000_STATUS_LU)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
		wufc &= ~E1000_WUFC_LNKC;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
	if (wufc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
		e1000_setup_rctl(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
		e1000_set_rx_mode(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
		rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
		/* turn on all-multi mode if wake on multicast is enabled */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
		if (wufc & E1000_WUFC_MC)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
			rctl |= E1000_RCTL_MPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
		/* enable receives in the hardware */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
		ew32(RCTL, rctl | E1000_RCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
		if (hw->mac_type >= e1000_82540) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
			ctrl = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
			/* advertise wake from D3Cold */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
			#define E1000_CTRL_ADVD3WUC 0x00100000
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
			/* phy power management enable */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
			ctrl |= E1000_CTRL_ADVD3WUC |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
				E1000_CTRL_EN_PHY_PWR_MGMT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
			ew32(CTRL, ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
		if (hw->media_type == e1000_media_type_fiber ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
		    hw->media_type == e1000_media_type_internal_serdes) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
			/* keep the laser running in D3 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
			ctrl_ext = er32(CTRL_EXT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
			ew32(CTRL_EXT, ctrl_ext);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
		ew32(WUC, E1000_WUC_PME_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
		ew32(WUFC, wufc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
		ew32(WUC, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
		ew32(WUFC, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
	e1000_release_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
	*enable_wake = !!wufc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
	/* make sure adapter isn't asleep if manageability is enabled */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
	if (adapter->en_mng_pt)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
		*enable_wake = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
		e1000_free_irq(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
	pci_disable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
	int retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
	bool wake;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
	retval = __e1000_shutdown(pdev, &wake);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
	if (retval)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
		return retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
	if (wake) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
		pci_prepare_to_sleep(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
		pci_wake_from_d3(pdev, false);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
		pci_set_power_state(pdev, PCI_D3hot);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
static int e1000_resume(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
	u32 err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
	pci_set_power_state(pdev, PCI_D0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
	pci_restore_state(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
	pci_save_state(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
	if (adapter->need_ioport)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
		err = pci_enable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
		err = pci_enable_device_mem(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
	if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
		pr_err("Cannot enable PCI device from suspend\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
		return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
	pci_set_master(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
	pci_enable_wake(pdev, PCI_D3hot, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
	pci_enable_wake(pdev, PCI_D3cold, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
	if (netif_running(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
		err = e1000_request_irq(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
		if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
			return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
	e1000_power_up_phy(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
	ew32(WUS, ~0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
	e1000_init_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
		e1000_up(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
	netif_device_attach(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
static void e1000_shutdown(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
	bool wake;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
	__e1000_shutdown(pdev, &wake);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
	if (system_state == SYSTEM_POWER_OFF) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
		pci_wake_from_d3(pdev, wake);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
		pci_set_power_state(pdev, PCI_D3hot);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
#ifdef CONFIG_NET_POLL_CONTROLLER
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
 * Polling 'interrupt' - used by things like netconsole to send skbs
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
 * without having to re-enable interrupts. It's not called while
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
 * the interrupt routine is executing.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
static void e1000_netpoll(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
	disable_irq(adapter->pdev->irq);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
	e1000_intr(adapter->pdev->irq, netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
	enable_irq(adapter->pdev->irq);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
 * e1000_io_error_detected - called when PCI error is detected
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
 * @pdev: Pointer to PCI device
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
 * @state: The current pci connection state
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
 * This function is called after a PCI bus error affecting
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
 * this device has been detected.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
						pci_channel_state_t state)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
	netif_device_detach(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
	if (state == pci_channel_io_perm_failure)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
		return PCI_ERS_RESULT_DISCONNECT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
		e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
	pci_disable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
	/* Request a slot slot reset. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
	return PCI_ERS_RESULT_NEED_RESET;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
 * e1000_io_slot_reset - called after the pci bus has been reset.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
 * @pdev: Pointer to PCI device
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
 * Restart the card from scratch, as if from a cold-boot. Implementation
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
 * resembles the first-half of the e1000_resume routine.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
	int err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
	if (adapter->need_ioport)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
		err = pci_enable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
		err = pci_enable_device_mem(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
	if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
		pr_err("Cannot re-enable PCI device after reset.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
		return PCI_ERS_RESULT_DISCONNECT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
	pci_set_master(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
	pci_enable_wake(pdev, PCI_D3hot, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	pci_enable_wake(pdev, PCI_D3cold, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
	ew32(WUS, ~0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
	return PCI_ERS_RESULT_RECOVERED;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
 * e1000_io_resume - called when traffic can start flowing again.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
 * @pdev: Pointer to PCI device
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
 * This callback is called when the error recovery driver tells us that
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
 * its OK to resume normal operation. Implementation resembles the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
 * second-half of the e1000_resume routine.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
static void e1000_io_resume(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
	e1000_init_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
	if (netif_running(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
		if (e1000_up(adapter)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
			pr_info("can't bring device back up after reset\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
			return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
	netif_device_attach(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
/* e1000_main.c */