devices/e1000/e1000_main-2.6.18-orig.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 667 9feff35c9617
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.
667
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
  
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it 
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms of the GNU General Public License as published by the Free 
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  Software Foundation; either version 2 of the License, or (at your option) 
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
  any later version.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  This program is distributed in the hope that it will be useful, but WITHOUT 
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
  more details.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  You should have received a copy of the GNU General Public License along with
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  this program; if not, write to the Free Software Foundation, Inc., 59 
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  The full GNU General Public License is included in this distribution in the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
  file called LICENSE.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Contact Information:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  Linux NICS <linux.nics@intel.com>
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
*******************************************************************************/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include "e1000.h"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
char e1000_driver_name[] = "e1000";
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#ifndef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#define DRIVERNAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#define DRIVERNAPI "-NAPI"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#define DRV_VERSION "7.1.9-k4"DRIVERNAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
char e1000_driver_version[] = DRV_VERSION;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
/* e1000_pci_tbl - PCI Device ID Table
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
 * Last entry must be all 0s
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
 * Macro expands to...
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
static struct pci_device_id e1000_pci_tbl[] = {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x1049),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x104A),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x104B),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x104C),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x104D),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x105E),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	INTEL_E1000_ETHERNET_DEVICE(0x105F),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	INTEL_E1000_ETHERNET_DEVICE(0x1060),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
	INTEL_E1000_ETHERNET_DEVICE(0x107D),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	INTEL_E1000_ETHERNET_DEVICE(0x107E),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
	INTEL_E1000_ETHERNET_DEVICE(0x107F),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	INTEL_E1000_ETHERNET_DEVICE(0x108B),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
	INTEL_E1000_ETHERNET_DEVICE(0x108C),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	INTEL_E1000_ETHERNET_DEVICE(0x1096),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
	INTEL_E1000_ETHERNET_DEVICE(0x1098),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
	INTEL_E1000_ETHERNET_DEVICE(0x109A),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	INTEL_E1000_ETHERNET_DEVICE(0x10B9),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	INTEL_E1000_ETHERNET_DEVICE(0x10BA),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	INTEL_E1000_ETHERNET_DEVICE(0x10BB),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	/* required last entry */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	{0,}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
};
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
                                    struct e1000_tx_ring *txdr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
                                    struct e1000_rx_ring *rxdr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
                                    struct e1000_tx_ring *tx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
                                    struct e1000_rx_ring *rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
/* Local Function Prototypes */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
static int e1000_init_module(void);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_exit_module(void);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void __devexit e1000_remove(struct pci_dev *pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static int e1000_alloc_queues(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static int e1000_sw_init(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static int e1000_open(struct net_device *netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static int e1000_close(struct net_device *netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static void e1000_configure_tx(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static void e1000_configure_rx(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static void e1000_setup_rctl(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
                                struct e1000_tx_ring *tx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
                                struct e1000_rx_ring *rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static void e1000_set_multi(struct net_device *netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
static void e1000_update_phy_info(unsigned long data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
static void e1000_watchdog(unsigned long data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
static void e1000_82547_tx_fifo_stall(unsigned long data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
static int e1000_set_mac(struct net_device *netdev, void *p);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
                                    struct e1000_tx_ring *tx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
static int e1000_clean(struct net_device *poll_dev, int *budget);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
                                    struct e1000_rx_ring *rx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
                                    int *work_done, int work_to_do);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
                                       struct e1000_rx_ring *rx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
                                       int *work_done, int work_to_do);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
#else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
                                    struct e1000_rx_ring *rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
                                       struct e1000_rx_ring *rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
                                   struct e1000_rx_ring *rx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
				   int cleaned_count);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
                                      struct e1000_rx_ring *rx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
				      int cleaned_count);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
			   int cmd);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
static void e1000_tx_timeout(struct net_device *dev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
static void e1000_reset_task(struct net_device *dev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
static void e1000_smartspeed(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
                                       struct sk_buff *skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
static void e1000_restore_vlan(struct e1000_adapter *adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
#ifdef CONFIG_PM
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
static int e1000_resume(struct pci_dev *pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
static void e1000_shutdown(struct pci_dev *pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
#ifdef CONFIG_NET_POLL_CONTROLLER
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
/* for netdump / net console */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
static void e1000_netpoll (struct net_device *netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
                     pci_channel_state_t state);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
static void e1000_io_resume(struct pci_dev *pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
static struct pci_error_handlers e1000_err_handler = {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	.error_detected = e1000_io_error_detected,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	.slot_reset = e1000_io_slot_reset,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	.resume = e1000_io_resume,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
};
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
static struct pci_driver e1000_driver = {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	.name     = e1000_driver_name,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	.id_table = e1000_pci_tbl,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	.probe    = e1000_probe,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	.remove   = __devexit_p(e1000_remove),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	/* Power Managment Hooks */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	.suspend  = e1000_suspend,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
#ifdef CONFIG_PM
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	.resume   = e1000_resume,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	.shutdown = e1000_shutdown,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
	.err_handler = &e1000_err_handler
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
};
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
MODULE_LICENSE("GPL");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
MODULE_VERSION(DRV_VERSION);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
module_param(debug, int, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
 * e1000_init_module - Driver Registration Routine
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
 * e1000_init_module is the first routine called when the driver is
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
 * loaded. All it does is register with the PCI subsystem.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
static int __init
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
e1000_init_module(void)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	int ret;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	printk(KERN_INFO "%s - version %s\n",
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
	       e1000_driver_string, e1000_driver_version);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
	printk(KERN_INFO "%s\n", e1000_copyright);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	ret = pci_module_init(&e1000_driver);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	return ret;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
module_init(e1000_init_module);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
 * e1000_exit_module - Driver Exit Cleanup Routine
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
 * e1000_exit_module is called just before the driver is removed
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
 * from memory.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
static void __exit
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
e1000_exit_module(void)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	pci_unregister_driver(&e1000_driver);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
module_exit(e1000_exit_module);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
static int e1000_request_irq(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	int flags, err = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	flags = IRQF_SHARED;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
#ifdef CONFIG_PCI_MSI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	if (adapter->hw.mac_type > e1000_82547_rev_2) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		adapter->have_msi = TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		if ((err = pci_enable_msi(adapter->pdev))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
			DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
			 "Unable to allocate MSI interrupt Error: %d\n", err);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
			adapter->have_msi = FALSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	if (adapter->have_msi)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		flags &= ~IRQF_SHARED;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	if ((err = request_irq(adapter->pdev->irq, &e1000_intr, flags,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	                       netdev->name, netdev)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
		DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
		        "Unable to allocate interrupt Error: %d\n", err);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	return err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
static void e1000_free_irq(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	free_irq(adapter->pdev->irq, netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
#ifdef CONFIG_PCI_MSI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	if (adapter->have_msi)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
		pci_disable_msi(adapter->pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
 * e1000_irq_disable - Mask off interrupt generation on the NIC
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
e1000_irq_disable(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	atomic_inc(&adapter->irq_sem);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	E1000_WRITE_REG(&adapter->hw, IMC, ~0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	E1000_WRITE_FLUSH(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	synchronize_irq(adapter->pdev->irq);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
 * e1000_irq_enable - Enable default interrupt generation settings
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
e1000_irq_enable(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		E1000_WRITE_FLUSH(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
e1000_update_mng_vlan(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	uint16_t vid = adapter->hw.mng_cookie.vlan_id;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	uint16_t old_vid = adapter->mng_vlan_id;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	if (adapter->vlgrp) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		if (!adapter->vlgrp->vlan_devices[vid]) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
			if (adapter->hw.mng_cookie.status &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
				e1000_vlan_rx_add_vid(netdev, vid);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
				adapter->mng_vlan_id = vid;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
			} else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
			if ((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
					(vid != old_vid) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
					!adapter->vlgrp->vlan_devices[old_vid])
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
				e1000_vlan_rx_kill_vid(netdev, old_vid);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
		} else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
			adapter->mng_vlan_id = vid;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
 * e1000_release_hw_control - release control of the h/w to f/w
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
 * @adapter: address of board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
 * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
 * For ASF and Pass Through versions of f/w this means that the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
 * driver is no longer loaded. For AMT version (only with 82573) i
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
 * of the f/w this means that the netowrk i/f is closed.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
e1000_release_hw_control(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	uint32_t ctrl_ext;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	uint32_t swsm;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
	uint32_t extcnf;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	/* Let firmware taken over control of h/w */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	switch (adapter->hw.mac_type) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
	case e1000_82571:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	case e1000_82572:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
	case e1000_80003es2lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	case e1000_82573:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
		swsm = E1000_READ_REG(&adapter->hw, SWSM);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
		E1000_WRITE_REG(&adapter->hw, SWSM,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
				swsm & ~E1000_SWSM_DRV_LOAD);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	case e1000_ich8lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		extcnf = E1000_READ_REG(&adapter->hw, CTRL_EXT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
				extcnf & ~E1000_CTRL_EXT_DRV_LOAD);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
 * e1000_get_hw_control - get control of the h/w from f/w
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
 * @adapter: address of board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
 * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
 * For ASF and Pass Through versions of f/w this means that
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
 * the driver is loaded. For AMT version (only with 82573)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
 * of the f/w this means that the netowrk i/f is open.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
e1000_get_hw_control(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	uint32_t ctrl_ext;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	uint32_t swsm;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	uint32_t extcnf;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	/* Let firmware know the driver has taken over */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	switch (adapter->hw.mac_type) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	case e1000_82571:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	case e1000_82572:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	case e1000_80003es2lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
	case e1000_82573:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
		swsm = E1000_READ_REG(&adapter->hw, SWSM);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
		E1000_WRITE_REG(&adapter->hw, SWSM,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
				swsm | E1000_SWSM_DRV_LOAD);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	case e1000_ich8lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
		extcnf = E1000_READ_REG(&adapter->hw, EXTCNF_CTRL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
		E1000_WRITE_REG(&adapter->hw, EXTCNF_CTRL,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
				extcnf | E1000_EXTCNF_CTRL_SWFLAG);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
e1000_up(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	/* hardware has been reset, we need to reload some things */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	e1000_set_multi(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	e1000_restore_vlan(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	e1000_configure_tx(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	e1000_setup_rctl(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	e1000_configure_rx(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	/* call E1000_DESC_UNUSED which always leaves
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	 * at least 1 descriptor unused to make sure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	 * next_to_use != next_to_clean */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	for (i = 0; i < adapter->num_rx_queues; i++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
		adapter->alloc_rx_buf(adapter, ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		                      E1000_DESC_UNUSED(ring));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	adapter->tx_queue_len = netdev->tx_queue_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	mod_timer(&adapter->watchdog_timer, jiffies);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	netif_poll_enable(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	e1000_irq_enable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
 * e1000_power_up_phy - restore link in case the phy was powered down
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
 * @adapter: address of board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
 * The phy may be powered down to save power and turn off link when the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
 * driver is unloaded and wake on lan is not enabled (among others)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
 * *** this routine MUST be followed by a call to e1000_reset ***
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
static void e1000_power_up_phy(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	uint16_t mii_reg = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	/* Just clear the power down bit to wake the phy back up */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	if (adapter->hw.media_type == e1000_media_type_copper) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		/* according to the manual, the phy will retain its
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		 * settings across a power-down/up cycle */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		mii_reg &= ~MII_CR_POWER_DOWN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
static void e1000_power_down_phy(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
	boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
	                              e1000_check_mng_mode(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	/* Power down the PHY so no link is implied when interface is down
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	 * The PHY cannot be powered down if any of the following is TRUE
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	 * (a) WoL is enabled
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	 * (b) AMT is active
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	 * (c) SoL/IDER session is active */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
	    adapter->hw.mac_type != e1000_ich8lan &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	    adapter->hw.media_type == e1000_media_type_copper &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	    !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	    !mng_mode_enabled &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	    !e1000_check_phy_reset_block(&adapter->hw)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
		uint16_t mii_reg = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
		mii_reg |= MII_CR_POWER_DOWN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
		mdelay(1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
e1000_down(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	e1000_irq_disable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	del_timer_sync(&adapter->tx_fifo_stall_timer);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	del_timer_sync(&adapter->watchdog_timer);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	del_timer_sync(&adapter->phy_info_timer);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	netif_poll_disable(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	netdev->tx_queue_len = adapter->tx_queue_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	adapter->link_speed = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	adapter->link_duplex = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	netif_carrier_off(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	netif_stop_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	e1000_reset(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	e1000_clean_all_tx_rings(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	e1000_clean_all_rx_rings(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
e1000_reinit_locked(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	WARN_ON(in_interrupt());
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
		msleep(1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	e1000_down(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	e1000_up(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
	clear_bit(__E1000_RESETTING, &adapter->flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
e1000_reset(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	uint32_t pba, manc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	/* Repartition Pba for greater than 9k mtu
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	 * To take effect CTRL.RST is required.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	switch (adapter->hw.mac_type) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	case e1000_82547:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	case e1000_82547_rev_2:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		pba = E1000_PBA_30K;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	case e1000_82571:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	case e1000_82572:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	case e1000_80003es2lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
		pba = E1000_PBA_38K;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	case e1000_82573:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
		pba = E1000_PBA_12K;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	case e1000_ich8lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		pba = E1000_PBA_8K;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		pba = E1000_PBA_48K;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	if ((adapter->hw.mac_type != e1000_82573) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	   (adapter->netdev->mtu > E1000_RXBUFFER_8192))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		pba -= 8; /* allocate more FIFO for Tx */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	if (adapter->hw.mac_type == e1000_82547) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		adapter->tx_fifo_head = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		adapter->tx_fifo_size =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
			(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		atomic_set(&adapter->tx_fifo_stall, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	E1000_WRITE_REG(&adapter->hw, PBA, pba);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	/* flow control settings */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	/* Set the FC high water mark to 90% of the FIFO size.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	 * Required to clear last 3 LSB */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	/* We can't use 90% on small FIFOs because the remainder
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	 * would be less than 1 full frame.  In this case, we size
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	 * it to allow at least a full frame above the high water
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	 *  mark. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	if (pba < E1000_PBA_16K)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
		fc_high_water_mark = (pba * 1024) - 1600;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	adapter->hw.fc_high_water = fc_high_water_mark;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	adapter->hw.fc_low_water = fc_high_water_mark - 8;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	if (adapter->hw.mac_type == e1000_80003es2lan)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
		adapter->hw.fc_pause_time = 0xFFFF;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	adapter->hw.fc_send_xon = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	adapter->hw.fc = adapter->hw.original_fc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	/* Allow time for pending master requests to run */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	e1000_reset_hw(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	if (adapter->hw.mac_type >= e1000_82544)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		E1000_WRITE_REG(&adapter->hw, WUC, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	if (e1000_init_hw(&adapter->hw))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		DPRINTK(PROBE, ERR, "Hardware Error\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	e1000_update_mng_vlan(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	e1000_reset_adaptive(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	if (!adapter->smart_power_down &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	    (adapter->hw.mac_type == e1000_82571 ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	     adapter->hw.mac_type == e1000_82572)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
		uint16_t phy_data = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
		/* speed up time to link by disabling smart power down, ignore
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
		 * the return value of this function because there is nothing
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		 * different we would do if it failed */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		e1000_read_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		                   &phy_data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		phy_data &= ~IGP02E1000_PM_SPD;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		e1000_write_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		                    phy_data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	if (adapter->hw.mac_type < e1000_ich8lan)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	/* FIXME: this code is duplicate and wrong for PCI Express */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	if (adapter->en_mng_pt) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		manc = E1000_READ_REG(&adapter->hw, MANC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
		manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
		E1000_WRITE_REG(&adapter->hw, MANC, manc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
 * e1000_probe - Device Initialization Routine
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
 * @pdev: PCI device information struct
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
 * @ent: entry in e1000_pci_tbl
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
 * Returns 0 on success, negative on failure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
 * e1000_probe initializes an adapter identified by a pci_dev structure.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
 * The OS initialization, configuring of the adapter private structure,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
 * and a hardware reset occur.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
static int __devinit
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
e1000_probe(struct pci_dev *pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
            const struct pci_device_id *ent)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	struct net_device *netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	struct e1000_adapter *adapter;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	unsigned long mmio_start, mmio_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	unsigned long flash_start, flash_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	static int cards_found = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	static int e1000_ksp3_port_a = 0; /* global ksp3 port a indication */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
	int i, err, pci_using_dac;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	uint16_t eeprom_data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	if ((err = pci_enable_device(pdev)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
		return err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	    !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		pci_using_dac = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
	} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
		if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
		    (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
			E1000_ERR("No usable DMA configuration, aborting\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
			return err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		pci_using_dac = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
	if ((err = pci_request_regions(pdev, e1000_driver_name)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
		return err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	pci_set_master(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	if (!netdev) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
		err = -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
		goto err_alloc_etherdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	SET_MODULE_OWNER(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	SET_NETDEV_DEV(netdev, &pdev->dev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	pci_set_drvdata(pdev, netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	adapter->netdev = netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	adapter->pdev = pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	adapter->hw.back = adapter;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	adapter->msg_enable = (1 << debug) - 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	mmio_start = pci_resource_start(pdev, BAR_0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	mmio_len = pci_resource_len(pdev, BAR_0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	if (!adapter->hw.hw_addr) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
		err = -EIO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
		goto err_ioremap;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	for (i = BAR_1; i <= BAR_5; i++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
		if (pci_resource_len(pdev, i) == 0)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
			continue;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
		if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
			adapter->hw.io_base = pci_resource_start(pdev, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	netdev->open = &e1000_open;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	netdev->stop = &e1000_close;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	netdev->hard_start_xmit = &e1000_xmit_frame;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	netdev->get_stats = &e1000_get_stats;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	netdev->set_multicast_list = &e1000_set_multi;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	netdev->set_mac_address = &e1000_set_mac;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	netdev->change_mtu = &e1000_change_mtu;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	netdev->do_ioctl = &e1000_ioctl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	e1000_set_ethtool_ops(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	netdev->tx_timeout = &e1000_tx_timeout;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	netdev->watchdog_timeo = 5 * HZ;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	netdev->poll = &e1000_clean;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	netdev->weight = 64;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	netdev->vlan_rx_register = e1000_vlan_rx_register;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
#ifdef CONFIG_NET_POLL_CONTROLLER
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	netdev->poll_controller = e1000_netpoll;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	strcpy(netdev->name, pci_name(pdev));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	netdev->mem_start = mmio_start;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	netdev->mem_end = mmio_start + mmio_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	netdev->base_addr = adapter->hw.io_base;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	adapter->bd_number = cards_found;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	/* setup the private structure */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	if ((err = e1000_sw_init(adapter)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
		goto err_sw_init;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	/* Flash BAR mapping must happen after e1000_sw_init
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	 * because it depends on mac_type */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	if ((adapter->hw.mac_type == e1000_ich8lan) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	   (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
		flash_start = pci_resource_start(pdev, 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		flash_len = pci_resource_len(pdev, 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		adapter->hw.flash_address = ioremap(flash_start, flash_len);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		if (!adapter->hw.flash_address) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
			err = -EIO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
			goto err_flashmap;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	if ((err = e1000_check_phy_reset_block(&adapter->hw)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	/* if ksp3, indicate if it's port a being setup */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	if (pdev->device == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
			e1000_ksp3_port_a == 0)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		adapter->ksp3_port_a = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	e1000_ksp3_port_a++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	/* Reset for multiple KP3 adapters */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	if (e1000_ksp3_port_a == 4)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
		e1000_ksp3_port_a = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	if (adapter->hw.mac_type >= e1000_82543) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
		netdev->features = NETIF_F_SG |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
				   NETIF_F_HW_CSUM |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
				   NETIF_F_HW_VLAN_TX |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
				   NETIF_F_HW_VLAN_RX |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
				   NETIF_F_HW_VLAN_FILTER;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
		if (adapter->hw.mac_type == e1000_ich8lan)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
			netdev->features &= ~NETIF_F_HW_VLAN_FILTER;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
#ifdef NETIF_F_TSO
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	if ((adapter->hw.mac_type >= e1000_82544) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	   (adapter->hw.mac_type != e1000_82547))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		netdev->features |= NETIF_F_TSO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
#ifdef NETIF_F_TSO_IPV6
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	if (adapter->hw.mac_type > e1000_82547_rev_2)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
		netdev->features |= NETIF_F_TSO_IPV6;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	if (pci_using_dac)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		netdev->features |= NETIF_F_HIGHDMA;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	netdev->features |= NETIF_F_LLTX;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	/* initialize eeprom parameters */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	if (e1000_init_eeprom_params(&adapter->hw)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
		E1000_ERR("EEPROM initialization failed\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
		return -EIO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	/* before reading the EEPROM, reset the controller to
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	 * put the device in a known good starting state */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	e1000_reset_hw(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	/* make sure the EEPROM is good */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
		/* On some hardware the first attemp fails */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
		if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
			DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
			err = -EIO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
			goto err_eeprom;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
		} else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
			DPRINTK(PROBE, INFO, "The EEPROM Checksum failed in the first read, now OK\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	/* copy the MAC address out of the EEPROM */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	if (e1000_read_mac_addr(&adapter->hw))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
		DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	if (!is_valid_ether_addr(netdev->perm_addr)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
		err = -EIO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
		goto err_eeprom;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	e1000_read_part_num(&adapter->hw, &(adapter->part_num));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	e1000_get_bus_info(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	init_timer(&adapter->tx_fifo_stall_timer);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	adapter->tx_fifo_stall_timer.data = (unsigned long) adapter;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	init_timer(&adapter->watchdog_timer);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	adapter->watchdog_timer.function = &e1000_watchdog;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	adapter->watchdog_timer.data = (unsigned long) adapter;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	init_timer(&adapter->phy_info_timer);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	adapter->phy_info_timer.function = &e1000_update_phy_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	adapter->phy_info_timer.data = (unsigned long) adapter;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	INIT_WORK(&adapter->reset_task,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		(void (*)(void *))e1000_reset_task, netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	/* we're going to reset, so assume we have no link for now */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	netif_carrier_off(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	netif_stop_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	e1000_check_options(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	/* Initial Wake on LAN setting
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	 * If APM wake is enabled in the EEPROM,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	 * enable the ACPI Magic Packet filter
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	switch (adapter->hw.mac_type) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	case e1000_82542_rev2_0:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	case e1000_82542_rev2_1:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	case e1000_82543:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	case e1000_82544:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		e1000_read_eeprom(&adapter->hw,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	case e1000_ich8lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
		e1000_read_eeprom(&adapter->hw,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
			EEPROM_INIT_CONTROL1_REG, 1, &eeprom_data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		eeprom_apme_mask = E1000_EEPROM_ICH8_APME;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	case e1000_82546:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	case e1000_82546_rev_3:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	case e1000_82571:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	case e1000_80003es2lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
		if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1){
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
			e1000_read_eeprom(&adapter->hw,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
		/* Fall Through */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
		e1000_read_eeprom(&adapter->hw,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	if (eeprom_data & eeprom_apme_mask)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
		adapter->wol |= E1000_WUFC_MAG;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	/* print bus type/speed/width info */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	struct e1000_hw *hw = &adapter->hw;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		 (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
		((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		 (hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		((hw->bus_width == e1000_bus_width_64) ? "64-bit" :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		 (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		 (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
		 "32-bit"));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	for (i = 0; i < 6; i++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		printk("%2.2x%c", netdev->dev_addr[i], i == 5 ? '\n' : ':');
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	/* reset the hardware with the new settings */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	e1000_reset(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	/* If the controller is 82573 and f/w is AMT, do not set
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	 * DRV_LOAD until the interface is up.  For all other cases,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	 * let the f/w know that the h/w is now under the control
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	 * of the driver. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	if (adapter->hw.mac_type != e1000_82573 ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	    !e1000_check_mng_mode(&adapter->hw))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
		e1000_get_hw_control(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	strcpy(netdev->name, "eth%d");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	if ((err = register_netdev(netdev)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
		goto err_register;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	cards_found++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
err_register:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	if (adapter->hw.flash_address)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
		iounmap(adapter->hw.flash_address);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
err_flashmap:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
err_sw_init:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
err_eeprom:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	iounmap(adapter->hw.hw_addr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
err_ioremap:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	free_netdev(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
err_alloc_etherdev:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	pci_release_regions(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	return err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
 * e1000_remove - Device Removal Routine
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
 * @pdev: PCI device information struct
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
 * e1000_remove is called by the PCI subsystem to alert the driver
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
 * that it should release a PCI device.  The could be caused by a
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
 * Hot-Plug event, or because the driver is going to be removed from
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
 * memory.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
static void __devexit
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
e1000_remove(struct pci_dev *pdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	struct net_device *netdev = pci_get_drvdata(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	uint32_t manc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	flush_scheduled_work();
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	if (adapter->hw.mac_type >= e1000_82540 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	   adapter->hw.mac_type != e1000_ich8lan &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	   adapter->hw.media_type == e1000_media_type_copper) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		manc = E1000_READ_REG(&adapter->hw, MANC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
		if (manc & E1000_MANC_SMBUS_EN) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
			manc |= E1000_MANC_ARP_EN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
			E1000_WRITE_REG(&adapter->hw, MANC, manc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	 * would have already happened in close and is redundant. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	e1000_release_hw_control(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	unregister_netdev(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	for (i = 0; i < adapter->num_rx_queues; i++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
		dev_put(&adapter->polling_netdev[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	if (!e1000_check_phy_reset_block(&adapter->hw))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		e1000_phy_hw_reset(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	kfree(adapter->tx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	kfree(adapter->rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	kfree(adapter->polling_netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	iounmap(adapter->hw.hw_addr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	if (adapter->hw.flash_address)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		iounmap(adapter->hw.flash_address);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	pci_release_regions(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	free_netdev(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	pci_disable_device(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
 * @adapter: board private structure to initialize
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
 * e1000_sw_init initializes the Adapter private data structure.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
 * Fields are initialized based on PCI device information and
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
 * OS network device settings (MTU size).
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
static int __devinit
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
e1000_sw_init(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	struct e1000_hw *hw = &adapter->hw;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	/* PCI config space info */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	hw->vendor_id = pdev->vendor;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
	hw->device_id = pdev->device;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	hw->subsystem_id = pdev->subsystem_device;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	adapter->rx_ps_bsize0 = E1000_RXBUFFER_128;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	hw->max_frame_size = netdev->mtu +
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	/* identify the MAC */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	if (e1000_set_mac_type(hw)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
		DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		return -EIO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	switch (hw->mac_type) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	case e1000_82541:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	case e1000_82547:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
	case e1000_82541_rev_2:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
	case e1000_82547_rev_2:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		hw->phy_init_script = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	e1000_set_media_type(hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	hw->wait_autoneg_complete = FALSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	hw->tbi_compatibility_en = TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	hw->adaptive_ifs = TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	/* Copper options */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	if (hw->media_type == e1000_media_type_copper) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		hw->mdix = AUTO_ALL_MODES;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
		hw->disable_polarity_correction = FALSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		hw->master_slave = E1000_MASTER_SLAVE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	adapter->num_tx_queues = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	adapter->num_rx_queues = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	if (e1000_alloc_queues(adapter)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	for (i = 0; i < adapter->num_rx_queues; i++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
		adapter->polling_netdev[i].priv = adapter;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
		adapter->polling_netdev[i].poll = &e1000_clean;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
		adapter->polling_netdev[i].weight = 64;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		dev_hold(&adapter->polling_netdev[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
		set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
	spin_lock_init(&adapter->tx_queue_lock);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	atomic_set(&adapter->irq_sem, 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	spin_lock_init(&adapter->stats_lock);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
 * e1000_alloc_queues - Allocate memory for all rings
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
 * @adapter: board private structure to initialize
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
 * We allocate one ring per queue at run-time since we don't know the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
 * number of queues at compile-time.  The polling_netdev array is
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
 * intended for Multiqueue, but should work fine with a single queue.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
static int __devinit
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
e1000_alloc_queues(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	int size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	adapter->tx_ring = kmalloc(size, GFP_KERNEL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	if (!adapter->tx_ring)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	memset(adapter->tx_ring, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	adapter->rx_ring = kmalloc(size, GFP_KERNEL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	if (!adapter->rx_ring) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		kfree(adapter->tx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	memset(adapter->rx_ring, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	size = sizeof(struct net_device) * adapter->num_rx_queues;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	if (!adapter->polling_netdev) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
		kfree(adapter->tx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		kfree(adapter->rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	memset(adapter->polling_netdev, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	return E1000_SUCCESS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
 * e1000_open - Called when a network interface is made active
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
 * @netdev: network interface device structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
 * Returns 0 on success, negative value on failure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
 * The open entry point is called when a network interface is made
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
 * active by the system (IFF_UP).  At this point all resources needed
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
 * for transmit and receive operations are allocated, the interrupt
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
 * handler is registered with the OS, the watchdog timer is started,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
 * and the stack is notified that the interface is ready.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
e1000_open(struct net_device *netdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	int err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
	/* disallow open during test */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	if (test_bit(__E1000_DRIVER_TESTING, &adapter->flags))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		return -EBUSY;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
	/* allocate transmit descriptors */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	if ((err = e1000_setup_all_tx_resources(adapter)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		goto err_setup_tx;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	/* allocate receive descriptors */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	if ((err = e1000_setup_all_rx_resources(adapter)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		goto err_setup_rx;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	err = e1000_request_irq(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	if (err)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		goto err_up;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	e1000_power_up_phy(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	if ((err = e1000_up(adapter)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		goto err_up;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	if ((adapter->hw.mng_cookie.status &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		e1000_update_mng_vlan(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	/* If AMT is enabled, let the firmware know that the network
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	 * interface is now open */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
	if (adapter->hw.mac_type == e1000_82573 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
	    e1000_check_mng_mode(&adapter->hw))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		e1000_get_hw_control(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
	return E1000_SUCCESS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
err_up:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
	e1000_free_all_rx_resources(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
err_setup_rx:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	e1000_free_all_tx_resources(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
err_setup_tx:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	e1000_reset(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
	return err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
 * e1000_close - Disables a network interface
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
 * @netdev: network interface device structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
 * Returns 0, this is not allowed to fail
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
 * The close entry point is called when an interface is de-activated
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
 * by the OS.  The hardware is still under the drivers control, but
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
 * needs to be disabled.  A global MAC reset is issued to stop the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
 * hardware, and all transmit and receive resources are freed.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
e1000_close(struct net_device *netdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	e1000_down(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	e1000_power_down_phy(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	e1000_free_irq(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	e1000_free_all_tx_resources(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	e1000_free_all_rx_resources(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
	if ((adapter->hw.mng_cookie.status &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	/* If AMT is enabled, let the firmware know that the network
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	 * interface is now closed */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	if (adapter->hw.mac_type == e1000_82573 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	    e1000_check_mng_mode(&adapter->hw))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
		e1000_release_hw_control(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
 * @adapter: address of board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
 * @start: address of beginning of memory
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
 * @len: length of memory
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
static boolean_t
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
e1000_check_64k_bound(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		      void *start, unsigned long len)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	unsigned long begin = (unsigned long) start;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	unsigned long end = begin + len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	/* First rev 82545 and 82546 need to not allow any memory
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	 * write location to cross 64k boundary due to errata 23 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	if (adapter->hw.mac_type == e1000_82545 ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	    adapter->hw.mac_type == e1000_82546) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
		return ((begin ^ (end - 1)) >> 16) != 0 ? FALSE : TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	return TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
 * @txdr:    tx descriptor ring (for a specific queue) to setup
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
 * Return 0 on success, negative on failure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
e1000_setup_tx_resources(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
                         struct e1000_tx_ring *txdr)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	int size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	size = sizeof(struct e1000_buffer) * txdr->count;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	txdr->buffer_info = vmalloc(size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	if (!txdr->buffer_info) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
		DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		"Unable to allocate memory for the transmit descriptor ring\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	memset(txdr->buffer_info, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	/* round up to nearest 4K */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	E1000_ROUNDUP(txdr->size, 4096);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	if (!txdr->desc) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
setup_tx_desc_die:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
		vfree(txdr->buffer_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
		DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
		"Unable to allocate memory for the transmit descriptor ring\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	/* Fix for errata 23, can't cross 64kB boundary */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		void *olddesc = txdr->desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
		dma_addr_t olddma = txdr->dma;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
		DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
				     "at %p\n", txdr->size, txdr->desc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
		/* Try again, without freeing the previous */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
		/* Failed allocation, critical failure */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
		if (!txdr->desc) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
			goto setup_tx_desc_die;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
			/* give up */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
			pci_free_consistent(pdev, txdr->size, txdr->desc,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
					    txdr->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
			DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
				"Unable to allocate aligned memory "
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
				"for the transmit descriptor ring\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
			vfree(txdr->buffer_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
			return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
			/* Free old allocation, new allocation was successful */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	memset(txdr->desc, 0, txdr->size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	txdr->next_to_use = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	txdr->next_to_clean = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	spin_lock_init(&txdr->tx_lock);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
 * 				  (Descriptors) for all queues
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
 * If this function returns with an error, then it's possible one or
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
 * more of the rings is populated (while the rest are not).  It is the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
 * callers duty to clean those orphaned rings.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
 * Return 0 on success, negative on failure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	int i, err = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
	for (i = 0; i < adapter->num_tx_queues; i++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
		if (err) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
			DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
				"Allocation for Tx Queue %u failed\n", i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	return err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
 * Configure the Tx unit of the MAC after a reset.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
e1000_configure_tx(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	uint64_t tdba;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	struct e1000_hw *hw = &adapter->hw;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	uint32_t tdlen, tctl, tipg, tarc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	uint32_t ipgr1, ipgr2;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	/* Setup the HW Tx Head and Tail descriptor pointers */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
	switch (adapter->num_tx_queues) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	case 1:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
		tdba = adapter->tx_ring[0].dma;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
		tdlen = adapter->tx_ring[0].count *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
			sizeof(struct e1000_tx_desc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
		E1000_WRITE_REG(hw, TDLEN, tdlen);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
		E1000_WRITE_REG(hw, TDBAH, (tdba >> 32));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
		E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		E1000_WRITE_REG(hw, TDT, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
		E1000_WRITE_REG(hw, TDH, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	/* Set the default values for the Tx Inter Packet Gap timer */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	if (hw->media_type == e1000_media_type_fiber ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	    hw->media_type == e1000_media_type_internal_serdes)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	switch (hw->mac_type) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	case e1000_82542_rev2_0:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	case e1000_82542_rev2_1:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
		tipg = DEFAULT_82542_TIPG_IPGT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	case e1000_80003es2lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	E1000_WRITE_REG(hw, TIPG, tipg);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	/* Set the Tx Interrupt Delay register */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
	if (hw->mac_type >= e1000_82540)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
		E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	/* Program the Transmit Control Register */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	tctl = E1000_READ_REG(hw, TCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	tctl &= ~E1000_TCTL_CT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
#ifdef DISABLE_MULR
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	/* disable Multiple Reads for debugging */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	tctl &= ~E1000_TCTL_MULR;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		tarc = E1000_READ_REG(hw, TARC0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		tarc |= ((1 << 25) | (1 << 21));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
		E1000_WRITE_REG(hw, TARC0, tarc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
		tarc = E1000_READ_REG(hw, TARC1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		tarc |= (1 << 25);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		if (tctl & E1000_TCTL_MULR)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
			tarc &= ~(1 << 28);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
			tarc |= (1 << 28);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
		E1000_WRITE_REG(hw, TARC1, tarc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	} else if (hw->mac_type == e1000_80003es2lan) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
		tarc = E1000_READ_REG(hw, TARC0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
		tarc |= 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		if (hw->media_type == e1000_media_type_internal_serdes)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
			tarc |= (1 << 20);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		E1000_WRITE_REG(hw, TARC0, tarc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		tarc = E1000_READ_REG(hw, TARC1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
		tarc |= 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
		E1000_WRITE_REG(hw, TARC1, tarc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	e1000_config_collision_dist(hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	/* Setup Transmit Descriptor Settings for eop descriptor */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	adapter->txd_cmd = E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		E1000_TXD_CMD_IFCS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	if (hw->mac_type < e1000_82543)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	/* Cache if we're 82544 running in PCI-X because we'll
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	 * need this to apply a workaround later in the send path. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	if (hw->mac_type == e1000_82544 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	    hw->bus_type == e1000_bus_type_pcix)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
		adapter->pcix_82544 = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	E1000_WRITE_REG(hw, TCTL, tctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
 * Returns 0 on success, negative on failure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
e1000_setup_rx_resources(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
                         struct e1000_rx_ring *rxdr)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	int size, desc_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	size = sizeof(struct e1000_buffer) * rxdr->count;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
	rxdr->buffer_info = vmalloc(size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
	if (!rxdr->buffer_info) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		"Unable to allocate memory for the receive descriptor ring\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	memset(rxdr->buffer_info, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	size = sizeof(struct e1000_ps_page) * rxdr->count;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
	rxdr->ps_page = kmalloc(size, GFP_KERNEL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
	if (!rxdr->ps_page) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		vfree(rxdr->buffer_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
		DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		"Unable to allocate memory for the receive descriptor ring\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	memset(rxdr->ps_page, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	size = sizeof(struct e1000_ps_page_dma) * rxdr->count;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
	rxdr->ps_page_dma = kmalloc(size, GFP_KERNEL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	if (!rxdr->ps_page_dma) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		vfree(rxdr->buffer_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
		kfree(rxdr->ps_page);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
		DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
		"Unable to allocate memory for the receive descriptor ring\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	memset(rxdr->ps_page_dma, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	if (adapter->hw.mac_type <= e1000_82547_rev_2)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
		desc_len = sizeof(struct e1000_rx_desc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
		desc_len = sizeof(union e1000_rx_desc_packet_split);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
	/* Round up to nearest 4K */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
	rxdr->size = rxdr->count * desc_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	E1000_ROUNDUP(rxdr->size, 4096);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	if (!rxdr->desc) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
		DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
		"Unable to allocate memory for the receive descriptor ring\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
setup_rx_desc_die:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		vfree(rxdr->buffer_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		kfree(rxdr->ps_page);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		kfree(rxdr->ps_page_dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	/* Fix for errata 23, can't cross 64kB boundary */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
		void *olddesc = rxdr->desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		dma_addr_t olddma = rxdr->dma;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
				     "at %p\n", rxdr->size, rxdr->desc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		/* Try again, without freeing the previous */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		/* Failed allocation, critical failure */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		if (!rxdr->desc) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
			DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
				"Unable to allocate memory "
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
				"for the receive descriptor ring\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
			goto setup_rx_desc_die;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
			/* give up */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
			pci_free_consistent(pdev, rxdr->size, rxdr->desc,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
					    rxdr->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
			DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
				"Unable to allocate aligned memory "
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
				"for the receive descriptor ring\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
			goto setup_rx_desc_die;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
			/* Free old allocation, new allocation was successful */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	memset(rxdr->desc, 0, rxdr->size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
	rxdr->next_to_clean = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	rxdr->next_to_use = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
 * 				  (Descriptors) for all queues
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
 * If this function returns with an error, then it's possible one or
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
 * more of the rings is populated (while the rest are not).  It is the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 * callers duty to clean those orphaned rings.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
 * Return 0 on success, negative on failure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	int i, err = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
	for (i = 0; i < adapter->num_rx_queues; i++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		if (err) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
			DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
				"Allocation for Rx Queue %u failed\n", i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	return err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
 * e1000_setup_rctl - configure the receive control registers
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
 * @adapter: Board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
e1000_setup_rctl(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	uint32_t rctl, rfctl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	uint32_t psrctl = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	uint32_t pages = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	rctl = E1000_READ_REG(&adapter->hw, RCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		(adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	if (adapter->hw.tbi_compatibility_on == 1)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
		rctl |= E1000_RCTL_SBP;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
		rctl &= ~E1000_RCTL_SBP;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
		rctl &= ~E1000_RCTL_LPE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		rctl |= E1000_RCTL_LPE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	/* Setup buffer sizes */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	rctl &= ~E1000_RCTL_SZ_4096;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	rctl |= E1000_RCTL_BSEX;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	switch (adapter->rx_buffer_len) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		case E1000_RXBUFFER_256:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
			rctl |= E1000_RCTL_SZ_256;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
			rctl &= ~E1000_RCTL_BSEX;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
		case E1000_RXBUFFER_512:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
			rctl |= E1000_RCTL_SZ_512;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
			rctl &= ~E1000_RCTL_BSEX;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
		case E1000_RXBUFFER_1024:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
			rctl |= E1000_RCTL_SZ_1024;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
			rctl &= ~E1000_RCTL_BSEX;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
		case E1000_RXBUFFER_2048:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
		default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
			rctl |= E1000_RCTL_SZ_2048;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
			rctl &= ~E1000_RCTL_BSEX;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		case E1000_RXBUFFER_4096:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
			rctl |= E1000_RCTL_SZ_4096;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
		case E1000_RXBUFFER_8192:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
			rctl |= E1000_RCTL_SZ_8192;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
		case E1000_RXBUFFER_16384:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
			rctl |= E1000_RCTL_SZ_16384;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
	/* 82571 and greater support packet-split where the protocol
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	 * header is placed in skb->data and the packet data is
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	 * In the case of a non-split, skb->data is linearly filled,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
	 * followed by the page buffers.  Therefore, skb->data is
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	 * sized to hold the largest protocol header.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
	 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	    PAGE_SIZE <= 16384)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
		adapter->rx_ps_pages = pages;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		adapter->rx_ps_pages = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	if (adapter->rx_ps_pages) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		/* Configure extra packet-split registers */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
		rfctl |= E1000_RFCTL_EXTEN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		/* disable IPv6 packet split support */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
		rfctl |= E1000_RFCTL_IPV6_DIS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
		rctl |= E1000_RCTL_DTYP_PS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		psrctl |= adapter->rx_ps_bsize0 >>
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			E1000_PSRCTL_BSIZE0_SHIFT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
		switch (adapter->rx_ps_pages) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		case 3:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
			psrctl |= PAGE_SIZE <<
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
				E1000_PSRCTL_BSIZE3_SHIFT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		case 2:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
			psrctl |= PAGE_SIZE <<
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
				E1000_PSRCTL_BSIZE2_SHIFT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		case 1:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
			psrctl |= PAGE_SIZE >>
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
				E1000_PSRCTL_BSIZE1_SHIFT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
 * Configure the Rx unit of the MAC after a reset.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
e1000_configure_rx(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
	uint64_t rdba;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	struct e1000_hw *hw = &adapter->hw;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
	uint32_t rdlen, rctl, rxcsum, ctrl_ext;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
	if (adapter->rx_ps_pages) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
		/* this is a 32 byte descriptor */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
		rdlen = adapter->rx_ring[0].count *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
			sizeof(union e1000_rx_desc_packet_split);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
		adapter->clean_rx = e1000_clean_rx_irq_ps;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
	} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		rdlen = adapter->rx_ring[0].count *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
			sizeof(struct e1000_rx_desc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
		adapter->clean_rx = e1000_clean_rx_irq;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	/* disable receives while setting up the descriptors */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	rctl = E1000_READ_REG(hw, RCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	/* set the Receive Delay Timer Register */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	if (hw->mac_type >= e1000_82540) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		if (adapter->itr > 1)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
			E1000_WRITE_REG(hw, ITR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
				1000000000 / (adapter->itr * 256));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	if (hw->mac_type >= e1000_82571) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		/* Reset delay timers after every interrupt */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
		ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
		/* Auto-Mask interrupts upon ICR read. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		ctrl_ext |= E1000_CTRL_EXT_IAME;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		E1000_WRITE_REG(hw, IAM, ~0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		E1000_WRITE_FLUSH(hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	 * the Base and Length of the Rx Descriptor Ring */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	switch (adapter->num_rx_queues) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	case 1:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
		rdba = adapter->rx_ring[0].dma;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		E1000_WRITE_REG(hw, RDLEN, rdlen);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
		E1000_WRITE_REG(hw, RDBAH, (rdba >> 32));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
		E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		E1000_WRITE_REG(hw, RDT, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
		E1000_WRITE_REG(hw, RDH, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
	if (hw->mac_type >= e1000_82543) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
		rxcsum = E1000_READ_REG(hw, RXCSUM);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
		if (adapter->rx_csum == TRUE) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
			rxcsum |= E1000_RXCSUM_TUOFL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
			/* Enable 82571 IPv4 payload checksum for UDP fragments
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
			 * Must be used in conjunction with packet-split. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
			if ((hw->mac_type >= e1000_82571) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
			    (adapter->rx_ps_pages)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
				rxcsum |= E1000_RXCSUM_IPPCSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
			rxcsum &= ~E1000_RXCSUM_TUOFL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
			/* don't need to clear IPPCSE as it defaults to 0 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
		E1000_WRITE_REG(hw, RXCSUM, rxcsum);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	/* Enable Receives */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	E1000_WRITE_REG(hw, RCTL, rctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
 * e1000_free_tx_resources - Free Tx Resources per Queue
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
 * @tx_ring: Tx descriptor ring for a specific queue
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
 * Free all transmit software resources
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
e1000_free_tx_resources(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
                        struct e1000_tx_ring *tx_ring)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	e1000_clean_tx_ring(adapter, tx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	vfree(tx_ring->buffer_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	tx_ring->buffer_info = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	tx_ring->desc = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
 * Free all transmit software resources
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
e1000_free_all_tx_resources(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
	for (i = 0; i < adapter->num_tx_queues; i++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
			struct e1000_buffer *buffer_info)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	if (buffer_info->dma) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
		pci_unmap_page(adapter->pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
				buffer_info->dma,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
				buffer_info->length,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
				PCI_DMA_TODEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	if (buffer_info->skb)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
		dev_kfree_skb_any(buffer_info->skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	memset(buffer_info, 0, sizeof(struct e1000_buffer));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
 * e1000_clean_tx_ring - Free Tx Buffers
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
 * @tx_ring: ring to be cleaned
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
e1000_clean_tx_ring(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
                    struct e1000_tx_ring *tx_ring)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	struct e1000_buffer *buffer_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	unsigned long size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	unsigned int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
	/* Free all the Tx ring sk_buffs */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	for (i = 0; i < tx_ring->count; i++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
		buffer_info = &tx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	size = sizeof(struct e1000_buffer) * tx_ring->count;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	memset(tx_ring->buffer_info, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	/* Zero out the descriptor ring */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	memset(tx_ring->desc, 0, tx_ring->size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	tx_ring->next_to_use = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	tx_ring->next_to_clean = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
	tx_ring->last_tx_tso = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	writel(0, adapter->hw.hw_addr + tx_ring->tdh);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	writel(0, adapter->hw.hw_addr + tx_ring->tdt);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	for (i = 0; i < adapter->num_tx_queues; i++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
 * e1000_free_rx_resources - Free Rx Resources
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
 * @rx_ring: ring to clean the resources from
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
 * Free all receive software resources
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
e1000_free_rx_resources(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
                        struct e1000_rx_ring *rx_ring)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	e1000_clean_rx_ring(adapter, rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	vfree(rx_ring->buffer_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	rx_ring->buffer_info = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	kfree(rx_ring->ps_page);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	rx_ring->ps_page = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	kfree(rx_ring->ps_page_dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
	rx_ring->ps_page_dma = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	rx_ring->desc = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
 * Free all receive software resources
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
e1000_free_all_rx_resources(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	for (i = 0; i < adapter->num_rx_queues; i++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
 * @rx_ring: ring to free buffers from
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
e1000_clean_rx_ring(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
                    struct e1000_rx_ring *rx_ring)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	struct e1000_buffer *buffer_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	struct e1000_ps_page *ps_page;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	struct e1000_ps_page_dma *ps_page_dma;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	unsigned long size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	unsigned int i, j;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	/* Free all the Rx ring sk_buffs */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	for (i = 0; i < rx_ring->count; i++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
		buffer_info = &rx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
		if (buffer_info->skb) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
			pci_unmap_single(pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
					 buffer_info->dma,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
					 buffer_info->length,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
					 PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
			dev_kfree_skb(buffer_info->skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
			buffer_info->skb = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		ps_page = &rx_ring->ps_page[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
		ps_page_dma = &rx_ring->ps_page_dma[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
		for (j = 0; j < adapter->rx_ps_pages; j++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
			if (!ps_page->ps_page[j]) break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
			pci_unmap_page(pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
				       ps_page_dma->ps_page_dma[j],
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
				       PAGE_SIZE, PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			ps_page_dma->ps_page_dma[j] = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
			put_page(ps_page->ps_page[j]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
			ps_page->ps_page[j] = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	size = sizeof(struct e1000_buffer) * rx_ring->count;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	memset(rx_ring->buffer_info, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	size = sizeof(struct e1000_ps_page) * rx_ring->count;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	memset(rx_ring->ps_page, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	size = sizeof(struct e1000_ps_page_dma) * rx_ring->count;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	memset(rx_ring->ps_page_dma, 0, size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
	/* Zero out the descriptor ring */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	memset(rx_ring->desc, 0, rx_ring->size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
	rx_ring->next_to_clean = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	rx_ring->next_to_use = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	writel(0, adapter->hw.hw_addr + rx_ring->rdh);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	writel(0, adapter->hw.hw_addr + rx_ring->rdt);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	for (i = 0; i < adapter->num_rx_queues; i++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
 * and memory write and invalidate disabled for certain operations
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
e1000_enter_82542_rst(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	uint32_t rctl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	e1000_pci_clear_mwi(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	rctl = E1000_READ_REG(&adapter->hw, RCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	rctl |= E1000_RCTL_RST;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
	E1000_WRITE_FLUSH(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
	mdelay(5);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
	if (netif_running(netdev))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
		e1000_clean_all_rx_rings(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
e1000_leave_82542_rst(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	uint32_t rctl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	rctl = E1000_READ_REG(&adapter->hw, RCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
	rctl &= ~E1000_RCTL_RST;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
	E1000_WRITE_FLUSH(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
	mdelay(5);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
	if (adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
		e1000_pci_set_mwi(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	if (netif_running(netdev)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
		/* No need to loop, because 82542 supports only 1 queue */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
		e1000_configure_rx(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
 * e1000_set_mac - Change the Ethernet Address of the NIC
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
 * @netdev: network interface device structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 * @p: pointer to an address structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
 * Returns 0 on success, negative on failure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
e1000_set_mac(struct net_device *netdev, void *p)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	struct sockaddr *addr = p;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	if (!is_valid_ether_addr(addr->sa_data))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
		return -EADDRNOTAVAIL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	/* 82542 2.0 needs to be in reset to write receive address registers */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
	if (adapter->hw.mac_type == e1000_82542_rev2_0)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
		e1000_enter_82542_rst(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
	e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
	/* With 82571 controllers, LAA may be overwritten (with the default)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	 * due to controller reset from the other port. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	if (adapter->hw.mac_type == e1000_82571) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		/* activate the work around */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
		adapter->hw.laa_is_present = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
		/* Hold a copy of the LAA in RAR[14] This is done so that
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
		 * between the time RAR[0] gets clobbered  and the time it
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		 * of the RARs and no incoming packets directed to this port
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
		 * are dropped. Eventaully the LAA will be in RAR[0] and
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
		 * RAR[14] */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
					E1000_RAR_ENTRIES - 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	if (adapter->hw.mac_type == e1000_82542_rev2_0)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
		e1000_leave_82542_rst(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
 * e1000_set_multi - Multicast and Promiscuous mode set
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
 * @netdev: network interface device structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
 * The set_multi entry point is called whenever the multicast address
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
 * list or the network interface flags are updated.  This routine is
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
 * responsible for configuring the hardware for proper multicast,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
 * promiscuous mode, and all-multi behavior.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
e1000_set_multi(struct net_device *netdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
	struct e1000_hw *hw = &adapter->hw;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	struct dev_mc_list *mc_ptr;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
	uint32_t rctl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	uint32_t hash_value;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	int i, rar_entries = E1000_RAR_ENTRIES;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
				E1000_NUM_MTA_REGISTERS_ICH8LAN :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
				E1000_NUM_MTA_REGISTERS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	if (adapter->hw.mac_type == e1000_ich8lan)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
		rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	/* reserve RAR[14] for LAA over-write work-around */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	if (adapter->hw.mac_type == e1000_82571)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
		rar_entries--;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	/* Check for Promiscuous and All Multicast modes */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	rctl = E1000_READ_REG(hw, RCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	if (netdev->flags & IFF_PROMISC) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
	} else if (netdev->flags & IFF_ALLMULTI) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
		rctl |= E1000_RCTL_MPE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
		rctl &= ~E1000_RCTL_UPE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
	} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
		rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	E1000_WRITE_REG(hw, RCTL, rctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	/* 82542 2.0 needs to be in reset to write receive address registers */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
	if (hw->mac_type == e1000_82542_rev2_0)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
		e1000_enter_82542_rst(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	/* load the first 14 multicast address into the exact filters 1-14
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	 * RAR 0 is used for the station MAC adddress
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
	 * if there are not 14 addresses, go ahead and clear the filters
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	 * -- with 82571 controllers only 0-13 entries are filled here
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	mc_ptr = netdev->mc_list;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	for (i = 1; i < rar_entries; i++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
		if (mc_ptr) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
			e1000_rar_set(hw, mc_ptr->dmi_addr, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
			mc_ptr = mc_ptr->next;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
			E1000_WRITE_FLUSH(hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
			E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
			E1000_WRITE_FLUSH(hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	/* clear the old settings from the multicast hash table */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	for (i = 0; i < mta_reg_count; i++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
		E1000_WRITE_FLUSH(hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	/* load any remaining addresses into the hash table */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
	for (; mc_ptr; mc_ptr = mc_ptr->next) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
		hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		e1000_mta_set(hw, hash_value);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
	if (hw->mac_type == e1000_82542_rev2_0)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
		e1000_leave_82542_rst(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
/* Need to wait a few seconds after link up to get diagnostic information from
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
 * the phy */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
e1000_update_phy_info(unsigned long data)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
 * e1000_82547_tx_fifo_stall - Timer Call-back
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
 * @data: pointer to adapter cast into an unsigned long
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
e1000_82547_tx_fifo_stall(unsigned long data)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	uint32_t tctl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
	if (atomic_read(&adapter->tx_fifo_stall)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
		if ((E1000_READ_REG(&adapter->hw, TDT) ==
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
		    E1000_READ_REG(&adapter->hw, TDH)) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
		   (E1000_READ_REG(&adapter->hw, TDFT) ==
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
		    E1000_READ_REG(&adapter->hw, TDFH)) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
		   (E1000_READ_REG(&adapter->hw, TDFTS) ==
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
		    E1000_READ_REG(&adapter->hw, TDFHS))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
			tctl = E1000_READ_REG(&adapter->hw, TCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
			E1000_WRITE_REG(&adapter->hw, TCTL,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
					tctl & ~E1000_TCTL_EN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
			E1000_WRITE_REG(&adapter->hw, TDFT,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
					adapter->tx_head_addr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
			E1000_WRITE_REG(&adapter->hw, TDFH,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
					adapter->tx_head_addr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
			E1000_WRITE_REG(&adapter->hw, TDFTS,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
					adapter->tx_head_addr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
			E1000_WRITE_REG(&adapter->hw, TDFHS,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
					adapter->tx_head_addr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
			E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
			E1000_WRITE_FLUSH(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
			adapter->tx_fifo_head = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
			atomic_set(&adapter->tx_fifo_stall, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
			netif_wake_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
 * e1000_watchdog - Timer Call-back
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
 * @data: pointer to adapter cast into an unsigned long
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
e1000_watchdog(unsigned long data)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	struct e1000_tx_ring *txdr = adapter->tx_ring;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
	uint32_t link, tctl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	int32_t ret_val;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	ret_val = e1000_check_for_link(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
	if ((ret_val == E1000_ERR_PHY) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	    (adapter->hw.phy_type == e1000_phy_igp_3) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
	    (E1000_READ_REG(&adapter->hw, CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
		/* See e1000_kumeran_lock_loss_workaround() */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		DPRINTK(LINK, INFO,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
			"Gigabit has been disabled, downgrading speed\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
	if (adapter->hw.mac_type == e1000_82573) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
		e1000_enable_tx_pkt_filtering(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
		if (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
			e1000_update_mng_vlan(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
	if ((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	   !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
		link = !adapter->hw.serdes_link_down;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
		link = E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	if (link) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
		if (!netif_carrier_ok(netdev)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
			boolean_t txb2b = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
			e1000_get_speed_and_duplex(&adapter->hw,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
			                           &adapter->link_speed,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
			                           &adapter->link_duplex);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
			DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s\n",
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
			       adapter->link_speed,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
			       adapter->link_duplex == FULL_DUPLEX ?
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
			       "Full Duplex" : "Half Duplex");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
			/* tweak tx_queue_len according to speed/duplex
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
			 * and adjust the timeout factor */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
			netdev->tx_queue_len = adapter->tx_queue_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
			adapter->tx_timeout_factor = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			switch (adapter->link_speed) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			case SPEED_10:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
				txb2b = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
				netdev->tx_queue_len = 10;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
				adapter->tx_timeout_factor = 8;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
				break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
			case SPEED_100:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
				txb2b = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
				netdev->tx_queue_len = 100;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
				/* maybe add some timeout factor ? */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
				break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
			if ((adapter->hw.mac_type == e1000_82571 ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
			     adapter->hw.mac_type == e1000_82572) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
			    txb2b == 0) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
#define SPEED_MODE_BIT (1 << 21)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
				uint32_t tarc0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
				tarc0 = E1000_READ_REG(&adapter->hw, TARC0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
				tarc0 &= ~SPEED_MODE_BIT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
				E1000_WRITE_REG(&adapter->hw, TARC0, tarc0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
				
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
#ifdef NETIF_F_TSO
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
			/* disable TSO for pcie and 10/100 speeds, to avoid
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
			 * some hardware issues */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
			if (!adapter->tso_force &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
			    adapter->hw.bus_type == e1000_bus_type_pci_express){
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
				switch (adapter->link_speed) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
				case SPEED_10:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
				case SPEED_100:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
					DPRINTK(PROBE,INFO,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
				        "10/100 speed: disabling TSO\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
					netdev->features &= ~NETIF_F_TSO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
					break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
				case SPEED_1000:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
					netdev->features |= NETIF_F_TSO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
					break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
				default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
					/* oops */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
					break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
				}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
			/* enable transmits in the hardware, need to do this
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
			 * after setting TARC0 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
			tctl = E1000_READ_REG(&adapter->hw, TCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
			tctl |= E1000_TCTL_EN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
			E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
			netif_carrier_on(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
			netif_wake_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
			mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
			adapter->smartspeed = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
		if (netif_carrier_ok(netdev)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
			adapter->link_speed = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
			adapter->link_duplex = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
			DPRINTK(LINK, INFO, "NIC Link is Down\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
			netif_carrier_off(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
			netif_stop_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
			mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
			/* 80003ES2LAN workaround--
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
			 * For packet buffer work-around on link down event;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
			 * disable receives in the ISR and
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
			 * reset device here in the watchdog
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
			 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
			if (adapter->hw.mac_type == e1000_80003es2lan) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
				/* reset device */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
				schedule_work(&adapter->reset_task);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		e1000_smartspeed(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
	e1000_update_stats(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
	adapter->hw.tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
	adapter->tpt_old = adapter->stats.tpt;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
	adapter->hw.collision_delta = adapter->stats.colc - adapter->colc_old;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
	adapter->colc_old = adapter->stats.colc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
	adapter->gorcl_old = adapter->stats.gorcl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	adapter->gotcl_old = adapter->stats.gotcl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
	e1000_update_adaptive(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	if (!netif_carrier_ok(netdev)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
			/* We've lost link, so the controller stops DMA,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
			 * but we've got queued Tx work that's never going
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
			 * to get done, so reset controller to flush Tx.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
			 * (Do the reset outside of interrupt context). */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
			adapter->tx_timeout_count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
			schedule_work(&adapter->reset_task);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	/* Dynamic mode for Interrupt Throttle Rate (ITR) */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
	if (adapter->hw.mac_type >= e1000_82540 && adapter->itr == 1) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
		/* Symmetric Tx/Rx gets a reduced ITR=2000; Total
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
		 * asymmetrical Tx or Rx gets ITR=8000; everyone
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
		 * else is between 2000-8000. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
		uint32_t goc = (adapter->gotcl + adapter->gorcl) / 10000;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
		uint32_t dif = (adapter->gotcl > adapter->gorcl ?
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
			adapter->gotcl - adapter->gorcl :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
			adapter->gorcl - adapter->gotcl) / 10000;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
		uint32_t itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		E1000_WRITE_REG(&adapter->hw, ITR, 1000000000 / (itr * 256));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
	/* Cause software interrupt to ensure rx ring is cleaned */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
	/* Force detection of hung controller every watchdog period */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	adapter->detect_tx_hung = TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
	/* With 82571 controllers, LAA may be overwritten due to controller
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	 * reset from the other port. Set the appropriate LAA in RAR[0] */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	if (adapter->hw.mac_type == e1000_82571 && adapter->hw.laa_is_present)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	/* Reset the timer */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
#define E1000_TX_FLAGS_CSUM		0x00000001
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
#define E1000_TX_FLAGS_VLAN		0x00000002
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
#define E1000_TX_FLAGS_TSO		0x00000004
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
#define E1000_TX_FLAGS_IPV4		0x00000008
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
#define E1000_TX_FLAGS_VLAN_SHIFT	16
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
          struct sk_buff *skb)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
#ifdef NETIF_F_TSO
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	struct e1000_context_desc *context_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
	struct e1000_buffer *buffer_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
	unsigned int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
	uint32_t cmd_length = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
	uint16_t ipcse = 0, tucse, mss;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
	int err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	if (skb_is_gso(skb)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		if (skb_header_cloned(skb)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			if (err)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
				return err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
		mss = skb_shinfo(skb)->gso_size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
		if (skb->protocol == htons(ETH_P_IP)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
			skb->nh.iph->tot_len = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
			skb->nh.iph->check = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
			skb->h.th->check =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
				~csum_tcpudp_magic(skb->nh.iph->saddr,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
						   skb->nh.iph->daddr,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
						   0,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
						   IPPROTO_TCP,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
						   0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
			cmd_length = E1000_TXD_CMD_IP;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
			ipcse = skb->h.raw - skb->data - 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
#ifdef NETIF_F_TSO_IPV6
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
		} else if (skb->protocol == ntohs(ETH_P_IPV6)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
			skb->nh.ipv6h->payload_len = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
			skb->h.th->check =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
				~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
						 &skb->nh.ipv6h->daddr,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
						 0,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
						 IPPROTO_TCP,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
						 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
			ipcse = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
		ipcss = skb->nh.raw - skb->data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
		ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
		tucss = skb->h.raw - skb->data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
		tucso = (void *)&(skb->h.th->check) - (void *)skb->data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
		tucse = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
		i = tx_ring->next_to_use;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		buffer_info = &tx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
		context_desc->upper_setup.tcp_fields.tucss = tucss;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
		context_desc->upper_setup.tcp_fields.tucso = tucso;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
		buffer_info->time_stamp = jiffies;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
		if (++i == tx_ring->count) i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
		tx_ring->next_to_use = i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
		return TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
	return FALSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
static boolean_t
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
              struct sk_buff *skb)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	struct e1000_context_desc *context_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	struct e1000_buffer *buffer_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	unsigned int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
	uint8_t css;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
	if (likely(skb->ip_summed == CHECKSUM_HW)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
		css = skb->h.raw - skb->data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
		i = tx_ring->next_to_use;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
		buffer_info = &tx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
		context_desc->upper_setup.tcp_fields.tucss = css;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
		context_desc->upper_setup.tcp_fields.tucso = css + skb->csum;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
		context_desc->upper_setup.tcp_fields.tucse = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		context_desc->tcp_seg_setup.data = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
		context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
		buffer_info->time_stamp = jiffies;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
		if (unlikely(++i == tx_ring->count)) i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
		tx_ring->next_to_use = i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
		return TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
	return FALSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
#define E1000_MAX_TXD_PWR	12
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
             struct sk_buff *skb, unsigned int first, unsigned int max_per_txd,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
             unsigned int nr_frags, unsigned int mss)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	struct e1000_buffer *buffer_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	unsigned int len = skb->len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	unsigned int offset = 0, size, count = 0, i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	unsigned int f;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	len -= skb->data_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	i = tx_ring->next_to_use;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
	while (len) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		buffer_info = &tx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
		size = min(len, max_per_txd);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
#ifdef NETIF_F_TSO
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
		/* Workaround for Controller erratum --
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
		 * descriptor for non-tso packet in a linear SKB that follows a
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
		 * tso gets written back prematurely before the data is fully
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
		 * DMA'd to the controller */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
		if (!skb->data_len && tx_ring->last_tx_tso &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
		    !skb_is_gso(skb)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
			tx_ring->last_tx_tso = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
			size -= 4;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
		/* Workaround for premature desc write-backs
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
		 * in TSO mode.  Append 4-byte sentinel desc */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
		if (unlikely(mss && !nr_frags && size == len && size > 8))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
			size -= 4;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
		/* work-around for errata 10 and it applies
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
		 * to all controllers in PCI-X mode
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
		 * The fix is to make sure that the first descriptor of a
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
		 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
		if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
		                (size > 2015) && count == 0))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
		        size = 2015;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
		 * terminating buffers within evenly-aligned dwords. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		if (unlikely(adapter->pcix_82544 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
		   size > 4))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
			size -= 4;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
		buffer_info->length = size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
		buffer_info->dma =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
			pci_map_single(adapter->pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
				skb->data + offset,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
				size,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
				PCI_DMA_TODEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
		buffer_info->time_stamp = jiffies;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
		len -= size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		offset += size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		if (unlikely(++i == tx_ring->count)) i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	for (f = 0; f < nr_frags; f++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
		struct skb_frag_struct *frag;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		frag = &skb_shinfo(skb)->frags[f];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
		len = frag->size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		offset = frag->page_offset;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		while (len) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
			buffer_info = &tx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
			size = min(len, max_per_txd);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
#ifdef NETIF_F_TSO
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
			/* Workaround for premature desc write-backs
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
			 * in TSO mode.  Append 4-byte sentinel desc */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
				size -= 4;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
			/* Workaround for potential 82544 hang in PCI-X.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
			 * Avoid terminating buffers within evenly-aligned
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
			 * dwords. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
			if (unlikely(adapter->pcix_82544 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
			   !((unsigned long)(frag->page+offset+size-1) & 4) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
			   size > 4))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
				size -= 4;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
			buffer_info->length = size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
			buffer_info->dma =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
				pci_map_page(adapter->pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
					frag->page,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
					offset,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
					size,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
					PCI_DMA_TODEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
			buffer_info->time_stamp = jiffies;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
			len -= size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
			offset += size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
			count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
			if (unlikely(++i == tx_ring->count)) i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
	i = (i == 0) ? tx_ring->count - 1 : i - 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	tx_ring->buffer_info[i].skb = skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
	tx_ring->buffer_info[first].next_to_watch = i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	return count;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
               int tx_flags, int count)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	struct e1000_tx_desc *tx_desc = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	struct e1000_buffer *buffer_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	unsigned int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		             E1000_TXD_CMD_TSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
		txd_lower |= E1000_TXD_CMD_VLE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
	i = tx_ring->next_to_use;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
	while (count--) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		buffer_info = &tx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		tx_desc = E1000_TX_DESC(*tx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		tx_desc->lower.data =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
			cpu_to_le32(txd_lower | buffer_info->length);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
		tx_desc->upper.data = cpu_to_le32(txd_upper);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		if (unlikely(++i == tx_ring->count)) i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	/* Force memory writes to complete before letting h/w
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
	 * know there are new descriptors to fetch.  (Only
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	 * applicable for weak-ordered memory model archs,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	 * such as IA-64). */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	wmb();
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	tx_ring->next_to_use = i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
	writel(i, adapter->hw.hw_addr + tx_ring->tdt);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
 * 82547 workaround to avoid controller hang in half-duplex environment.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
 * The workaround is to avoid queuing a large packet that would span
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
 * the internal Tx FIFO ring boundary by notifying the stack to resend
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
 * to the beginning of the Tx FIFO.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
#define E1000_FIFO_HDR			0x10
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
#define E1000_82547_PAD_LEN		0x3E0
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	uint32_t fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
	uint32_t skb_fifo_len = skb->len + E1000_FIFO_HDR;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
	E1000_ROUNDUP(skb_fifo_len, E1000_FIFO_HDR);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
	if (adapter->link_duplex != HALF_DUPLEX)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
		goto no_fifo_stall_required;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	if (atomic_read(&adapter->tx_fifo_stall))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
		return 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
		atomic_set(&adapter->tx_fifo_stall, 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
		return 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
no_fifo_stall_required:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
	adapter->tx_fifo_head += skb_fifo_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
#define MINIMUM_DHCP_PACKET_SIZE 282
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	struct e1000_hw *hw =  &adapter->hw;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
	uint16_t length, offset;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	if (vlan_tx_tag_present(skb)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
			( adapter->hw.mng_cookie.status &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
			return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	if (skb->len > MINIMUM_DHCP_PACKET_SIZE) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
		struct ethhdr *eth = (struct ethhdr *) skb->data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
		if ((htons(ETH_P_IP) == eth->h_proto)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
			const struct iphdr *ip =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
				(struct iphdr *)((uint8_t *)skb->data+14);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
			if (IPPROTO_UDP == ip->protocol) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
				struct udphdr *udp =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
					(struct udphdr *)((uint8_t *)ip +
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
						(ip->ihl << 2));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
				if (ntohs(udp->dest) == 67) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
					offset = (uint8_t *)udp + 8 - skb->data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
					length = skb->len - offset;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
					return e1000_mng_write_dhcp_info(hw,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
							(uint8_t *)udp + 8,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
							length);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
				}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
	struct e1000_tx_ring *tx_ring;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	unsigned int tx_flags = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
	unsigned int len = skb->len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	unsigned long flags;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	unsigned int nr_frags = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	unsigned int mss = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	int count = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	int tso;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
	unsigned int f;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	len -= skb->data_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	tx_ring = adapter->tx_ring;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	if (unlikely(skb->len <= 0)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		dev_kfree_skb_any(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		return NETDEV_TX_OK;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
#ifdef NETIF_F_TSO
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
	mss = skb_shinfo(skb)->gso_size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	/* The controller does a simple calculation to
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	 * make sure there is enough room in the FIFO before
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	 * initiating the DMA for each buffer.  The calc is:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	 * 4 = ceil(buffer len/mss).  To make sure we don't
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	 * overrun the FIFO, adjust the max buffer len if mss
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	 * drops. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
	if (mss) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
		uint8_t hdr_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
		max_per_txd = min(mss << 2, max_per_txd);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
		max_txd_pwr = fls(max_per_txd) - 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
	 * points to just header, pull a few bytes of payload from
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
	 * frags into skb->data */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
		if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
			switch (adapter->hw.mac_type) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
				unsigned int pull_size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
			case e1000_82571:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
			case e1000_82572:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
			case e1000_82573:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
			case e1000_ich8lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
				pull_size = min((unsigned int)4, skb->data_len);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
				if (!__pskb_pull_tail(skb, pull_size)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
					DPRINTK(DRV, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
						"__pskb_pull_tail failed.\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
					dev_kfree_skb_any(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
					return NETDEV_TX_OK;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
				}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
				len = skb->len - skb->data_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
				break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
			default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
				/* do nothing */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
				break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
	/* reserve a descriptor for the offload context */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
	if ((mss) || (skb->ip_summed == CHECKSUM_HW))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
	count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
#else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	if (skb->ip_summed == CHECKSUM_HW)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
#ifdef NETIF_F_TSO
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
	/* Controller Erratum workaround */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
		count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	count += TXD_USE_COUNT(len, max_txd_pwr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
	if (adapter->pcix_82544)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	/* work-around for errata 10 and it applies to all controllers
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	 * in PCI-X mode, so add one more descriptor to the count
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
	 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
			(len > 2015)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
		count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
	nr_frags = skb_shinfo(skb)->nr_frags;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	for (f = 0; f < nr_frags; f++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
				       max_txd_pwr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
	if (adapter->pcix_82544)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		count += nr_frags;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
	if (adapter->hw.tx_pkt_filtering &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
	    (adapter->hw.mac_type == e1000_82573))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
		e1000_transfer_dhcp_info(adapter, skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	local_irq_save(flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	if (!spin_trylock(&tx_ring->tx_lock)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
		/* Collision - tell upper layer to requeue */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		local_irq_restore(flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
		return NETDEV_TX_LOCKED;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	/* need: count + 2 desc gap to keep tail from touching
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
	 * head, otherwise try next time */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
	if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
		netif_stop_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
		return NETDEV_TX_BUSY;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
	if (unlikely(adapter->hw.mac_type == e1000_82547)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
			netif_stop_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
			return NETDEV_TX_BUSY;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
		tx_flags |= E1000_TX_FLAGS_VLAN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
	first = tx_ring->next_to_use;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
	tso = e1000_tso(adapter, tx_ring, skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
	if (tso < 0) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		dev_kfree_skb_any(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
		return NETDEV_TX_OK;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
	if (likely(tso)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
		tx_ring->last_tx_tso = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
		tx_flags |= E1000_TX_FLAGS_TSO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
		tx_flags |= E1000_TX_FLAGS_CSUM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	/* Old method was to assume IPv4 packet by default if TSO was enabled.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	 * no longer assume, we must. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	if (likely(skb->protocol == htons(ETH_P_IP)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
		tx_flags |= E1000_TX_FLAGS_IPV4;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	e1000_tx_queue(adapter, tx_ring, tx_flags,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	               e1000_tx_map(adapter, tx_ring, skb, first,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
	                            max_per_txd, nr_frags, mss));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	netdev->trans_start = jiffies;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	/* Make sure there is space in the ring for the next send. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
		netif_stop_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	return NETDEV_TX_OK;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
 * e1000_tx_timeout - Respond to a Tx Hang
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
 * @netdev: network interface device structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
e1000_tx_timeout(struct net_device *netdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	/* Do the reset outside of interrupt context */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	adapter->tx_timeout_count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	schedule_work(&adapter->reset_task);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
e1000_reset_task(struct net_device *netdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	e1000_reinit_locked(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
 * e1000_get_stats - Get System Network Statistics
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
 * @netdev: network interface device structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
 * Returns the address of the device statistics structure.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
 * The statistics are actually updated from the timer callback.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
static struct net_device_stats *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
e1000_get_stats(struct net_device *netdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
	/* only return the current stats */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
	return &adapter->net_stats;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
 * e1000_change_mtu - Change the Maximum Transfer Unit
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
 * @netdev: network interface device structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
 * @new_mtu: new value for maximum frame size
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
 * Returns 0 on success, negative on failure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
e1000_change_mtu(struct net_device *netdev, int new_mtu)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	uint16_t eeprom_data = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		return -EINVAL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
	/* Adapter-specific max frame size limits. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	switch (adapter->hw.mac_type) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
	case e1000_undefined ... e1000_82542_rev2_1:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	case e1000_ich8lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
			return -EINVAL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
	case e1000_82573:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
		/* only enable jumbo frames if ASPM is disabled completely
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		 * this means both bits must be zero in 0x1A bits 3:2 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
		e1000_read_eeprom(&adapter->hw, EEPROM_INIT_3GIO_3, 1,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
		                  &eeprom_data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
		if (eeprom_data & EEPROM_WORD1A_ASPM_MASK) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
			if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
				DPRINTK(PROBE, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
			            	"Jumbo Frames not supported.\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
				return -EINVAL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
		/* fall through to get support */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	case e1000_82571:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	case e1000_82572:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	case e1000_80003es2lan:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
#define MAX_STD_JUMBO_FRAME_SIZE 9234
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
		if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
			DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
			return -EINVAL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	 * means we reserve 2 more, this pushes us to allocate from the next
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	 * larger slab size
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	 * i.e. RXBUFFER_2048 --> size-4096 slab */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	if (max_frame <= E1000_RXBUFFER_256)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
		adapter->rx_buffer_len = E1000_RXBUFFER_256;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	else if (max_frame <= E1000_RXBUFFER_512)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
		adapter->rx_buffer_len = E1000_RXBUFFER_512;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	else if (max_frame <= E1000_RXBUFFER_1024)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		adapter->rx_buffer_len = E1000_RXBUFFER_1024;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	else if (max_frame <= E1000_RXBUFFER_2048)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	else if (max_frame <= E1000_RXBUFFER_4096)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
		adapter->rx_buffer_len = E1000_RXBUFFER_4096;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
	else if (max_frame <= E1000_RXBUFFER_8192)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		adapter->rx_buffer_len = E1000_RXBUFFER_8192;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	else if (max_frame <= E1000_RXBUFFER_16384)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	/* adjust allocation if LPE protects us, and we aren't using SBP */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	if (!adapter->hw.tbi_compatibility_on &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	    ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	netdev->mtu = new_mtu;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
	if (netif_running(netdev))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		e1000_reinit_locked(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
	adapter->hw.max_frame_size = max_frame;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
 * e1000_update_stats - Update the board statistics counters
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
e1000_update_stats(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
	struct e1000_hw *hw = &adapter->hw;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
	unsigned long flags;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	uint16_t phy_tmp;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	/*
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	 * Prevent stats update while adapter is being reset, or if the pci
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	 * connection is down.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	if (adapter->link_speed == 0)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
		return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	if (pdev->error_state && pdev->error_state != pci_channel_io_normal)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
		return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	spin_lock_irqsave(&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	/* these counters are modified from e1000_adjust_tbi_stats,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	 * called from the interrupt context, so they must only
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	 * be written while holding adapter->stats_lock
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	adapter->stats.crcerrs += E1000_READ_REG(hw, CRCERRS);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	adapter->stats.gprc += E1000_READ_REG(hw, GPRC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	adapter->stats.gorcl += E1000_READ_REG(hw, GORCL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	adapter->stats.gorch += E1000_READ_REG(hw, GORCH);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	adapter->stats.bprc += E1000_READ_REG(hw, BPRC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	adapter->stats.mprc += E1000_READ_REG(hw, MPRC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	adapter->stats.roc += E1000_READ_REG(hw, ROC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	if (adapter->hw.mac_type != e1000_ich8lan) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	adapter->stats.prc64 += E1000_READ_REG(hw, PRC64);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	adapter->stats.prc127 += E1000_READ_REG(hw, PRC127);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	adapter->stats.prc255 += E1000_READ_REG(hw, PRC255);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	adapter->stats.prc511 += E1000_READ_REG(hw, PRC511);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	adapter->stats.prc1023 += E1000_READ_REG(hw, PRC1023);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	adapter->stats.prc1522 += E1000_READ_REG(hw, PRC1522);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	adapter->stats.symerrs += E1000_READ_REG(hw, SYMERRS);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	adapter->stats.mpc += E1000_READ_REG(hw, MPC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	adapter->stats.scc += E1000_READ_REG(hw, SCC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	adapter->stats.ecol += E1000_READ_REG(hw, ECOL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	adapter->stats.mcc += E1000_READ_REG(hw, MCC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
	adapter->stats.latecol += E1000_READ_REG(hw, LATECOL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	adapter->stats.dc += E1000_READ_REG(hw, DC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	adapter->stats.sec += E1000_READ_REG(hw, SEC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	adapter->stats.rlec += E1000_READ_REG(hw, RLEC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	adapter->stats.xonrxc += E1000_READ_REG(hw, XONRXC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	adapter->stats.xontxc += E1000_READ_REG(hw, XONTXC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
	adapter->stats.xoffrxc += E1000_READ_REG(hw, XOFFRXC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	adapter->stats.xofftxc += E1000_READ_REG(hw, XOFFTXC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
	adapter->stats.fcruc += E1000_READ_REG(hw, FCRUC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	adapter->stats.gptc += E1000_READ_REG(hw, GPTC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	adapter->stats.gotcl += E1000_READ_REG(hw, GOTCL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	adapter->stats.gotch += E1000_READ_REG(hw, GOTCH);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	adapter->stats.rnbc += E1000_READ_REG(hw, RNBC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	adapter->stats.ruc += E1000_READ_REG(hw, RUC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	adapter->stats.rfc += E1000_READ_REG(hw, RFC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	adapter->stats.rjc += E1000_READ_REG(hw, RJC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	adapter->stats.torl += E1000_READ_REG(hw, TORL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	adapter->stats.torh += E1000_READ_REG(hw, TORH);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	adapter->stats.totl += E1000_READ_REG(hw, TOTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	adapter->stats.toth += E1000_READ_REG(hw, TOTH);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	adapter->stats.tpr += E1000_READ_REG(hw, TPR);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
	if (adapter->hw.mac_type != e1000_ich8lan) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	adapter->stats.ptc64 += E1000_READ_REG(hw, PTC64);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	adapter->stats.ptc127 += E1000_READ_REG(hw, PTC127);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	adapter->stats.ptc255 += E1000_READ_REG(hw, PTC255);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	adapter->stats.ptc511 += E1000_READ_REG(hw, PTC511);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
	adapter->stats.ptc1023 += E1000_READ_REG(hw, PTC1023);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	adapter->stats.ptc1522 += E1000_READ_REG(hw, PTC1522);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	adapter->stats.mptc += E1000_READ_REG(hw, MPTC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	adapter->stats.bptc += E1000_READ_REG(hw, BPTC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
	/* used for adaptive IFS */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
	hw->tx_packet_delta = E1000_READ_REG(hw, TPT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	adapter->stats.tpt += hw->tx_packet_delta;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	hw->collision_delta = E1000_READ_REG(hw, COLC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	adapter->stats.colc += hw->collision_delta;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
	if (hw->mac_type >= e1000_82543) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
		adapter->stats.algnerrc += E1000_READ_REG(hw, ALGNERRC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
		adapter->stats.rxerrc += E1000_READ_REG(hw, RXERRC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
		adapter->stats.tncrs += E1000_READ_REG(hw, TNCRS);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
		adapter->stats.cexterr += E1000_READ_REG(hw, CEXTERR);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
		adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
		adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	if (hw->mac_type > e1000_82547_rev_2) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
		adapter->stats.iac += E1000_READ_REG(hw, IAC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
		adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
		if (adapter->hw.mac_type != e1000_ich8lan) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
		adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
		adapter->stats.icrxatc += E1000_READ_REG(hw, ICRXATC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
		adapter->stats.ictxptc += E1000_READ_REG(hw, ICTXPTC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
		adapter->stats.ictxatc += E1000_READ_REG(hw, ICTXATC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
		adapter->stats.ictxqec += E1000_READ_REG(hw, ICTXQEC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
		adapter->stats.ictxqmtc += E1000_READ_REG(hw, ICTXQMTC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
		adapter->stats.icrxdmtc += E1000_READ_REG(hw, ICRXDMTC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	/* Fill out the OS statistics structure */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	adapter->net_stats.rx_packets = adapter->stats.gprc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	adapter->net_stats.tx_packets = adapter->stats.gptc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	adapter->net_stats.rx_bytes = adapter->stats.gorcl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	adapter->net_stats.tx_bytes = adapter->stats.gotcl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	adapter->net_stats.multicast = adapter->stats.mprc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	adapter->net_stats.collisions = adapter->stats.colc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	/* Rx Errors */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	/* RLEC on some newer hardware can be incorrect so build
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
	* our own version based on RUC and ROC */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
		adapter->stats.crcerrs + adapter->stats.algnerrc +
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
		adapter->stats.ruc + adapter->stats.roc +
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
		adapter->stats.cexterr;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	adapter->net_stats.rx_length_errors = adapter->stats.ruc +
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	                                      adapter->stats.roc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	/* Tx Errors */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
	adapter->net_stats.tx_errors = adapter->stats.ecol +
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	                               adapter->stats.latecol;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	/* Tx Dropped needs to be maintained elsewhere */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	/* Phy Stats */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	if (hw->media_type == e1000_media_type_copper) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
		if ((adapter->link_speed == SPEED_1000) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
			adapter->phy_stats.idle_errors += phy_tmp;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
		if ((hw->mac_type <= e1000_82546) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
		   (hw->phy_type == e1000_phy_m88) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
			adapter->phy_stats.receive_errors += phy_tmp;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	spin_unlock_irqrestore(&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
 * e1000_intr - Interrupt Handler
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
 * @irq: interrupt number
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
 * @data: pointer to a network interface device structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
 * @pt_regs: CPU registers structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
static irqreturn_t
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
e1000_intr(int irq, void *data, struct pt_regs *regs)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	struct net_device *netdev = data;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	struct e1000_hw *hw = &adapter->hw;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	uint32_t rctl, icr = E1000_READ_REG(hw, ICR);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
#ifndef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
#else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	/* Interrupt Auto-Mask...upon reading ICR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	 * interrupts are masked.  No need for the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	 * IMC write, but it does mean we should
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
	 * account for it ASAP. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
	if (likely(hw->mac_type >= e1000_82571))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
		atomic_inc(&adapter->irq_sem);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
	if (unlikely(!icr)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
		if (hw->mac_type >= e1000_82571)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
			e1000_irq_enable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
		return IRQ_NONE;  /* Not our interrupt */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
		hw->get_link_status = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
		/* 80003ES2LAN workaround--
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
		 * For packet buffer work-around on link down event;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
		 * disable receives here in the ISR and
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
		 * reset adapter in watchdog
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
		 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
		if (netif_carrier_ok(netdev) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
		    (adapter->hw.mac_type == e1000_80003es2lan)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
			/* disable receives */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
			rctl = E1000_READ_REG(hw, RCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
			E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
		mod_timer(&adapter->watchdog_timer, jiffies);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	if (unlikely(hw->mac_type < e1000_82571)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		atomic_inc(&adapter->irq_sem);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		E1000_WRITE_REG(hw, IMC, ~0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
		E1000_WRITE_FLUSH(hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	if (likely(netif_rx_schedule_prep(netdev)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
		__netif_rx_schedule(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
		e1000_irq_enable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
#else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	/* Writing IMC and IMS is needed for 82547.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
	 * Due to Hub Link bus being occupied, an interrupt
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	 * de-assertion message is not able to be sent.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	 * When an interrupt assertion message is generated later,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
	 * two messages are re-ordered and sent out.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
	 * That causes APIC to think 82547 is in de-assertion
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	 * state, while 82547 is in assertion state, resulting
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	 * in dead lock. Writing IMC forces 82547 into
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	 * de-assertion state.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
		atomic_inc(&adapter->irq_sem);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
		E1000_WRITE_REG(hw, IMC, ~0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
	for (i = 0; i < E1000_MAX_INTR; i++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		   !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
		e1000_irq_enable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	return IRQ_HANDLED;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
 * e1000_clean - NAPI Rx polling callback
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
e1000_clean(struct net_device *poll_dev, int *budget)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	struct e1000_adapter *adapter;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	int work_to_do = min(*budget, poll_dev->quota);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	int tx_cleaned = 0, work_done = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	/* Must NOT use netdev_priv macro here. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	adapter = poll_dev->priv;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	/* Keep link state information with original netdev */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
	if (!netif_carrier_ok(poll_dev))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
		goto quit_polling;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	/* e1000_clean is called per-cpu.  This lock protects
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	 * tx_ring[0] from being cleaned by multiple cpus
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	 * simultaneously.  A failure obtaining the lock means
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	 * tx_ring[0] is currently being cleaned anyway. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	if (spin_trylock(&adapter->tx_queue_lock)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		tx_cleaned = e1000_clean_tx_irq(adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		                                &adapter->tx_ring[0]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
		spin_unlock(&adapter->tx_queue_lock);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	adapter->clean_rx(adapter, &adapter->rx_ring[0],
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	                  &work_done, work_to_do);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	*budget -= work_done;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
	poll_dev->quota -= work_done;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	/* If no Tx and not enough Rx work done, exit the polling mode */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	if ((!tx_cleaned && (work_done == 0)) ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
	   !netif_running(poll_dev)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
quit_polling:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		netif_rx_complete(poll_dev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
		e1000_irq_enable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
	return 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
static boolean_t
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
e1000_clean_tx_irq(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
                   struct e1000_tx_ring *tx_ring)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	struct e1000_tx_desc *tx_desc, *eop_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	struct e1000_buffer *buffer_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	unsigned int i, eop;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	unsigned int count = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
	boolean_t cleaned = FALSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
	i = tx_ring->next_to_clean;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	eop = tx_ring->buffer_info[i].next_to_watch;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
		for (cleaned = FALSE; !cleaned; ) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
			tx_desc = E1000_TX_DESC(*tx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
			buffer_info = &tx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
			cleaned = (i == eop);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
			memset(tx_desc, 0, sizeof(struct e1000_tx_desc));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
			if (unlikely(++i == tx_ring->count)) i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
		eop = tx_ring->buffer_info[i].next_to_watch;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
#define E1000_TX_WEIGHT 64
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
		/* weight of a sort for tx, to avoid endless transmit cleanup */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
		if (count++ == E1000_TX_WEIGHT) break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	tx_ring->next_to_clean = i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
#define TX_WAKE_THRESHOLD 32
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	if (unlikely(cleaned && netif_queue_stopped(netdev) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	             netif_carrier_ok(netdev))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
		spin_lock(&tx_ring->tx_lock);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
		if (netif_queue_stopped(netdev) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		    (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
			netif_wake_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
		spin_unlock(&tx_ring->tx_lock);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
	if (adapter->detect_tx_hung) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
		/* Detect a transmit hang in hardware, this serializes the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
		 * check with the clearing of time_stamp and movement of i */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
		adapter->detect_tx_hung = FALSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
		if (tx_ring->buffer_info[eop].dma &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
		               (adapter->tx_timeout_factor * HZ))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
		    && !(E1000_READ_REG(&adapter->hw, STATUS) &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
		         E1000_STATUS_TXOFF)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
			/* detected Tx unit hang */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
					"  Tx Queue             <%lu>\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
					"  TDH                  <%x>\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
					"  TDT                  <%x>\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
					"  next_to_use          <%x>\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
					"  next_to_clean        <%x>\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
					"buffer_info[next_to_clean]\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
					"  time_stamp           <%lx>\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
					"  next_to_watch        <%x>\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
					"  jiffies              <%lx>\n"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
					"  next_to_watch.status <%x>\n",
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
				(unsigned long)((tx_ring - adapter->tx_ring) /
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
					sizeof(struct e1000_tx_ring)),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
				readl(adapter->hw.hw_addr + tx_ring->tdh),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
				readl(adapter->hw.hw_addr + tx_ring->tdt),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
				tx_ring->next_to_use,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
				tx_ring->next_to_clean,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
				tx_ring->buffer_info[eop].time_stamp,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
				eop,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
				jiffies,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
				eop_desc->upper.fields.status);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
			netif_stop_queue(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	return cleaned;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
 * e1000_rx_checksum - Receive Checksum Offload for 82543
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
 * @adapter:     board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
 * @status_err:  receive descriptor status and error fields
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
 * @csum:        receive descriptor csum field
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
 * @sk_buff:     socket buffer with received data
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
e1000_rx_checksum(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
		  uint32_t status_err, uint32_t csum,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
		  struct sk_buff *skb)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	uint16_t status = (uint16_t)status_err;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	uint8_t errors = (uint8_t)(status_err >> 24);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
	skb->ip_summed = CHECKSUM_NONE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
	/* 82543 or newer only */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
	if (unlikely(adapter->hw.mac_type < e1000_82543)) return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	/* Ignore Checksum bit is set */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
	/* TCP/UDP checksum error bit is set */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
		/* let the stack verify checksum errors */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
		adapter->hw_csum_err++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
		return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	/* TCP/UDP Checksum has not been calculated */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	if (adapter->hw.mac_type <= e1000_82547_rev_2) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
		if (!(status & E1000_RXD_STAT_TCPCS))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
			return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
		if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
			return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	/* It must be a TCP or UDP packet with a valid checksum */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
		/* TCP checksum is good */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
		skb->ip_summed = CHECKSUM_UNNECESSARY;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	} else if (adapter->hw.mac_type > e1000_82547_rev_2) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
		/* IP fragment with UDP payload */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
		/* Hardware complements the payload checksum, so we undo it
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
		 * and then put the value in host order for further stack use.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
		 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
		csum = ntohl(csum ^ 0xFFFF);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
		skb->csum = csum;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
		skb->ip_summed = CHECKSUM_HW;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
	adapter->hw_csum_good++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
static boolean_t
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
e1000_clean_rx_irq(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
                   struct e1000_rx_ring *rx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
                   int *work_done, int work_to_do)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
#else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
e1000_clean_rx_irq(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
                   struct e1000_rx_ring *rx_ring)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	struct e1000_rx_desc *rx_desc, *next_rxd;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
	struct e1000_buffer *buffer_info, *next_buffer;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	unsigned long flags;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	uint32_t length;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	uint8_t last_byte;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	unsigned int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	int cleaned_count = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	boolean_t cleaned = FALSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	i = rx_ring->next_to_clean;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	rx_desc = E1000_RX_DESC(*rx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
	buffer_info = &rx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
	while (rx_desc->status & E1000_RXD_STAT_DD) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
		struct sk_buff *skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
		u8 status;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		if (*work_done >= work_to_do)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
		(*work_done)++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
		status = rx_desc->status;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
		skb = buffer_info->skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
		buffer_info->skb = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
		prefetch(skb->data - NET_IP_ALIGN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
		if (++i == rx_ring->count) i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
		next_rxd = E1000_RX_DESC(*rx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
		prefetch(next_rxd);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
		next_buffer = &rx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
		cleaned = TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
		cleaned_count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
		pci_unmap_single(pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
		                 buffer_info->dma,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
		                 buffer_info->length,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
		                 PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
		length = le16_to_cpu(rx_desc->length);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
		/* adjust length to remove Ethernet CRC */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
		length -= 4;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
		if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
			/* All receives must fit into a single buffer */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
			E1000_DBG("%s: Receive packet consumed multiple"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
				  " buffers\n", netdev->name);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
			/* recycle */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
			buffer_info-> skb = skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
			goto next_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
			last_byte = *(skb->data + length - 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
			if (TBI_ACCEPT(&adapter->hw, status,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
			              rx_desc->errors, length, last_byte)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
				spin_lock_irqsave(&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
				e1000_tbi_adjust_stats(&adapter->hw,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
				                       &adapter->stats,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
				                       length, skb->data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
				spin_unlock_irqrestore(&adapter->stats_lock,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
				                       flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
				length--;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
			} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
				/* recycle */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
				buffer_info->skb = skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
				goto next_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
		/* code added for copybreak, this should improve
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
		 * performance for small packets with large amounts
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
		 * of reassembly being done in the stack */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
#define E1000_CB_LENGTH 256
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
		if (length < E1000_CB_LENGTH) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
			struct sk_buff *new_skb =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
			if (new_skb) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
				skb_reserve(new_skb, NET_IP_ALIGN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
				new_skb->dev = netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
				memcpy(new_skb->data - NET_IP_ALIGN,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
				       skb->data - NET_IP_ALIGN,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
				       length + NET_IP_ALIGN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
				/* save the skb in buffer_info as good */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
				buffer_info->skb = skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
				skb = new_skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
				skb_put(skb, length);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
		} else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
			skb_put(skb, length);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
		/* end copybreak code */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
		/* Receive Checksum Offload */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		e1000_rx_checksum(adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
				  (uint32_t)(status) |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
				  ((uint32_t)(rx_desc->errors) << 24),
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
				  le16_to_cpu(rx_desc->csum), skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		skb->protocol = eth_type_trans(skb, netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
		if (unlikely(adapter->vlgrp &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
			    (status & E1000_RXD_STAT_VP))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
						 le16_to_cpu(rx_desc->special) &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
						 E1000_RXD_SPC_VLAN_MASK);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
			netif_receive_skb(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
#else /* CONFIG_E1000_NAPI */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		if (unlikely(adapter->vlgrp &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
			    (status & E1000_RXD_STAT_VP))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
			vlan_hwaccel_rx(skb, adapter->vlgrp,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
					le16_to_cpu(rx_desc->special) &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
					E1000_RXD_SPC_VLAN_MASK);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
			netif_rx(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
#endif /* CONFIG_E1000_NAPI */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
		netdev->last_rx = jiffies;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
next_desc:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
		rx_desc->status = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
		/* return some buffers to hardware, one at a time is too slow */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
			cleaned_count = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
		/* use prefetched values */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
		rx_desc = next_rxd;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
		buffer_info = next_buffer;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	rx_ring->next_to_clean = i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	if (cleaned_count)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	return cleaned;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
 * @adapter: board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
static boolean_t
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
                      struct e1000_rx_ring *rx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
                      int *work_done, int work_to_do)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
#else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
                      struct e1000_rx_ring *rx_ring)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	struct e1000_buffer *buffer_info, *next_buffer;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
	struct e1000_ps_page *ps_page;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
	struct e1000_ps_page_dma *ps_page_dma;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
	struct sk_buff *skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
	unsigned int i, j;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
	uint32_t length, staterr;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
	int cleaned_count = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
	boolean_t cleaned = FALSE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
	i = rx_ring->next_to_clean;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
	buffer_info = &rx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
	while (staterr & E1000_RXD_STAT_DD) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
		ps_page = &rx_ring->ps_page[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
		ps_page_dma = &rx_ring->ps_page_dma[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
		if (unlikely(*work_done >= work_to_do))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
		(*work_done)++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
		skb = buffer_info->skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
		/* in the packet split case this is header only */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
		prefetch(skb->data - NET_IP_ALIGN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
		if (++i == rx_ring->count) i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
		prefetch(next_rxd);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
		next_buffer = &rx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
		cleaned = TRUE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
		cleaned_count++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
		pci_unmap_single(pdev, buffer_info->dma,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
				 buffer_info->length,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
				 PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
		if (unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
			E1000_DBG("%s: Packet Split buffers didn't pick up"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
				  " the full packet\n", netdev->name);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
			dev_kfree_skb_irq(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
			goto next_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		if (unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
			dev_kfree_skb_irq(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
			goto next_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		length = le16_to_cpu(rx_desc->wb.middle.length0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
		if (unlikely(!length)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
			E1000_DBG("%s: Last part of the packet spanning"
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
				  " multiple descriptors\n", netdev->name);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
			dev_kfree_skb_irq(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
			goto next_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
		/* Good Receive */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
		skb_put(skb, length);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
		{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
		/* this looks ugly, but it seems compiler issues make it
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
		   more efficient than reusing j */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
		int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
		/* page alloc/put takes too long and effects small packet
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
		 * throughput, so unsplit small packets and save the alloc/put*/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
		if (l1 && ((length + l1) <= adapter->rx_ps_bsize0)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
			u8 *vaddr;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
			/* there is no documentation about how to call
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
			 * kmap_atomic, so we can't hold the mapping
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
			 * very long */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
			pci_dma_sync_single_for_cpu(pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
				ps_page_dma->ps_page_dma[0],
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
				PAGE_SIZE,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
				PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
			vaddr = kmap_atomic(ps_page->ps_page[0],
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
			                    KM_SKB_DATA_SOFTIRQ);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
			memcpy(skb->tail, vaddr, l1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
			pci_dma_sync_single_for_device(pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
				ps_page_dma->ps_page_dma[0],
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
				PAGE_SIZE, PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
			/* remove the CRC */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
			l1 -= 4;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
			skb_put(skb, l1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
			goto copydone;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
		} /* if */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
		
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
		for (j = 0; j < adapter->rx_ps_pages; j++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
			if (!(length= le16_to_cpu(rx_desc->wb.upper.length[j])))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
				break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
			pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
					PAGE_SIZE, PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
			ps_page_dma->ps_page_dma[j] = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
			skb_fill_page_desc(skb, j, ps_page->ps_page[j], 0,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
			                   length);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
			ps_page->ps_page[j] = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
			skb->len += length;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
			skb->data_len += length;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
			skb->truesize += length;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		/* strip the ethernet crc, problem is we're using pages now so
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
		 * this whole operation can get a little cpu intensive */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		pskb_trim(skb, skb->len - 4);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
copydone:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
		e1000_rx_checksum(adapter, staterr,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
				  le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
		skb->protocol = eth_type_trans(skb, netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
		if (likely(rx_desc->wb.upper.header_status &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
			   cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
			adapter->rx_hdr_split++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
#ifdef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
		if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
				le16_to_cpu(rx_desc->wb.middle.vlan) &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
				E1000_RXD_SPC_VLAN_MASK);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
			netif_receive_skb(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
#else /* CONFIG_E1000_NAPI */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
		if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
			vlan_hwaccel_rx(skb, adapter->vlgrp,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
				le16_to_cpu(rx_desc->wb.middle.vlan) &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
				E1000_RXD_SPC_VLAN_MASK);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
			netif_rx(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
#endif /* CONFIG_E1000_NAPI */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
		netdev->last_rx = jiffies;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
next_desc:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
		buffer_info->skb = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
		/* return some buffers to hardware, one at a time is too slow */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
			cleaned_count = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
		/* use prefetched values */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
		rx_desc = next_rxd;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
		buffer_info = next_buffer;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
	rx_ring->next_to_clean = i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
	if (cleaned_count)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
	return cleaned;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
 * @adapter: address of board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
                       struct e1000_rx_ring *rx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
		       int cleaned_count)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	struct e1000_rx_desc *rx_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
	struct e1000_buffer *buffer_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	struct sk_buff *skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
	unsigned int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
	i = rx_ring->next_to_use;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
	buffer_info = &rx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
	while (cleaned_count--) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
		if (!(skb = buffer_info->skb))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
			skb = netdev_alloc_skb(netdev, bufsz);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
		else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
			skb_trim(skb, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
			goto map_skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
		if (unlikely(!skb)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
			/* Better luck next round */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
			adapter->alloc_rx_buff_failed++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
		/* Fix for errata 23, can't cross 64kB boundary */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
			struct sk_buff *oldskb = skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
			DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
					     "at %p\n", bufsz, skb->data);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
			/* Try again, without freeing the previous */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
			skb = netdev_alloc_skb(netdev, bufsz);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
			/* Failed allocation, critical failure */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
			if (!skb) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
				dev_kfree_skb(oldskb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
				break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
				/* give up */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
				dev_kfree_skb(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
				dev_kfree_skb(oldskb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
				break; /* while !buffer_info->skb */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
			} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
				/* Use new allocation */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
				dev_kfree_skb(oldskb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
		/* Make buffer alignment 2 beyond a 16 byte boundary
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
		 * this will result in a 16 byte aligned IP header after
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
		 * the 14 byte MAC header is removed
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
		 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		skb_reserve(skb, NET_IP_ALIGN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
		skb->dev = netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
		buffer_info->skb = skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
		buffer_info->length = adapter->rx_buffer_len;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
map_skb:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
		buffer_info->dma = pci_map_single(pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
						  skb->data,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
						  adapter->rx_buffer_len,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
						  PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
		/* Fix for errata 23, can't cross 64kB boundary */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
		if (!e1000_check_64k_bound(adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
					(void *)(unsigned long)buffer_info->dma,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
					adapter->rx_buffer_len)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
			DPRINTK(RX_ERR, ERR,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
				"dma align check failed: %u bytes at %p\n",
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
				adapter->rx_buffer_len,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
				(void *)(unsigned long)buffer_info->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
			dev_kfree_skb(skb);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
			buffer_info->skb = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
			pci_unmap_single(pdev, buffer_info->dma,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
					 adapter->rx_buffer_len,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
					 PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
			break; /* while !buffer_info->skb */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
		rx_desc = E1000_RX_DESC(*rx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
		if (unlikely(++i == rx_ring->count))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
			i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
		buffer_info = &rx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
	if (likely(rx_ring->next_to_use != i)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
		rx_ring->next_to_use = i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		if (unlikely(i-- == 0))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
			i = (rx_ring->count - 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
		/* Force memory writes to complete before letting h/w
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
		 * know there are new descriptors to fetch.  (Only
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
		 * applicable for weak-ordered memory model archs,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
		 * such as IA-64). */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
		wmb();
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
 * @adapter: address of board private structure
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
                          struct e1000_rx_ring *rx_ring,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
			  int cleaned_count)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
	struct net_device *netdev = adapter->netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
	struct pci_dev *pdev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
	union e1000_rx_desc_packet_split *rx_desc;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
	struct e1000_buffer *buffer_info;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
	struct e1000_ps_page *ps_page;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
	struct e1000_ps_page_dma *ps_page_dma;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	struct sk_buff *skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	unsigned int i, j;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	i = rx_ring->next_to_use;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	buffer_info = &rx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	ps_page = &rx_ring->ps_page[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
	ps_page_dma = &rx_ring->ps_page_dma[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	while (cleaned_count--) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
			if (j < adapter->rx_ps_pages) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
				if (likely(!ps_page->ps_page[j])) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
					ps_page->ps_page[j] =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
						alloc_page(GFP_ATOMIC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
					if (unlikely(!ps_page->ps_page[j])) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
						adapter->alloc_rx_buff_failed++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
						goto no_buffers;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
					}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
					ps_page_dma->ps_page_dma[j] =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
						pci_map_page(pdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
							    ps_page->ps_page[j],
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
							    0, PAGE_SIZE,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
							    PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
				}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
				/* Refresh the desc even if buffer_addrs didn't
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
				 * change because each write-back erases
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
				 * this info.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
				 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
				rx_desc->read.buffer_addr[j+1] =
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
				     cpu_to_le64(ps_page_dma->ps_page_dma[j]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
			} else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
				rx_desc->read.buffer_addr[j+1] = ~0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
		skb = netdev_alloc_skb(netdev,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
				       adapter->rx_ps_bsize0 + NET_IP_ALIGN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
		if (unlikely(!skb)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
			adapter->alloc_rx_buff_failed++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
			break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
		/* Make buffer alignment 2 beyond a 16 byte boundary
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
		 * this will result in a 16 byte aligned IP header after
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
		 * the 14 byte MAC header is removed
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
		 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
		skb_reserve(skb, NET_IP_ALIGN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
		skb->dev = netdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		buffer_info->skb = skb;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
		buffer_info->length = adapter->rx_ps_bsize0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
		buffer_info->dma = pci_map_single(pdev, skb->data,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
						  adapter->rx_ps_bsize0,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
						  PCI_DMA_FROMDEVICE);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
		if (unlikely(++i == rx_ring->count)) i = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
		buffer_info = &rx_ring->buffer_info[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
		ps_page = &rx_ring->ps_page[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
		ps_page_dma = &rx_ring->ps_page_dma[i];
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
no_buffers:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
	if (likely(rx_ring->next_to_use != i)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
		rx_ring->next_to_use = i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
		if (unlikely(i-- == 0)) i = (rx_ring->count - 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
		/* Force memory writes to complete before letting h/w
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		 * know there are new descriptors to fetch.  (Only
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
		 * applicable for weak-ordered memory model archs,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
		 * such as IA-64). */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
		wmb();
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
		/* Hardware increments by 16 bytes, but packet split
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
		 * descriptors are 32 bytes...so we increment tail
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		 * twice as much.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
		writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
 * @adapter:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
e1000_smartspeed(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
	uint16_t phy_status;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
	uint16_t phy_ctrl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	if ((adapter->hw.phy_type != e1000_phy_igp) || !adapter->hw.autoneg ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
	   !(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
		return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
	if (adapter->smartspeed == 0) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
		/* If Master/Slave config fault is asserted twice,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
		 * we assume back-to-back */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
		e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
			e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
					    phy_ctrl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
			adapter->smartspeed++;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
			if (!e1000_phy_setup_autoneg(&adapter->hw) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
			   !e1000_read_phy_reg(&adapter->hw, PHY_CTRL,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
				   	       &phy_ctrl)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
					     MII_CR_RESTART_AUTO_NEG);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
				e1000_write_phy_reg(&adapter->hw, PHY_CTRL,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
						    phy_ctrl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
		return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
		/* If still no link, perhaps using 2/3 pair cable */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
		e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
		phy_ctrl |= CR_1000T_MS_ENABLE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
		e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_ctrl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
		if (!e1000_phy_setup_autoneg(&adapter->hw) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
		   !e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_ctrl)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
				     MII_CR_RESTART_AUTO_NEG);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
			e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_ctrl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
		adapter->smartspeed = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
 * e1000_ioctl -
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
 * @netdev:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
 * @ifreq:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
 * @cmd:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
	switch (cmd) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
	case SIOCGMIIPHY:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
	case SIOCGMIIREG:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
	case SIOCSMIIREG:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
		return e1000_mii_ioctl(netdev, ifr, cmd);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
		return -EOPNOTSUPP;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
 * e1000_mii_ioctl -
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
 * @netdev:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
 * @ifreq:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
 * @cmd:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
 **/
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
	struct mii_ioctl_data *data = if_mii(ifr);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	int retval;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
	uint16_t mii_reg;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	uint16_t spddplx;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
	unsigned long flags;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
	if (adapter->hw.media_type != e1000_media_type_copper)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
		return -EOPNOTSUPP;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
	switch (cmd) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	case SIOCGMIIPHY:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
		data->phy_id = adapter->hw.phy_addr;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
	case SIOCGMIIREG:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
		if (!capable(CAP_NET_ADMIN))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
			return -EPERM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
		spin_lock_irqsave(&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
		if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
				   &data->val_out)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
			return -EIO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
	case SIOCSMIIREG:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
		if (!capable(CAP_NET_ADMIN))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
			return -EPERM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		if (data->reg_num & ~(0x1F))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
			return -EFAULT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
		mii_reg = data->val_in;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
		spin_lock_irqsave(&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
		if (e1000_write_phy_reg(&adapter->hw, data->reg_num,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
					mii_reg)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
			return -EIO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		if (adapter->hw.media_type == e1000_media_type_copper) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
			switch (data->reg_num) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
			case PHY_CTRL:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
				if (mii_reg & MII_CR_POWER_DOWN)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
					break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
					adapter->hw.autoneg = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
					adapter->hw.autoneg_advertised = 0x2F;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
				} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
					if (mii_reg & 0x40)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
						spddplx = SPEED_1000;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
					else if (mii_reg & 0x2000)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
						spddplx = SPEED_100;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
					else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
						spddplx = SPEED_10;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
					spddplx += (mii_reg & 0x100)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
						   ? DUPLEX_FULL :
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
						   DUPLEX_HALF;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
					retval = e1000_set_spd_dplx(adapter,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
								    spddplx);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
					if (retval) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
						spin_unlock_irqrestore(
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
							&adapter->stats_lock,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
							flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
						return retval;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
					}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
				}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
				if (netif_running(adapter->netdev))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
					e1000_reinit_locked(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
				else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
					e1000_reset(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
				break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
			case M88E1000_PHY_SPEC_CTRL:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
			case M88E1000_EXT_PHY_SPEC_CTRL:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
				if (e1000_phy_reset(&adapter->hw)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
					spin_unlock_irqrestore(
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
						&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
					return -EIO;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
				}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
				break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
		} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
			switch (data->reg_num) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
			case PHY_CTRL:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
				if (mii_reg & MII_CR_POWER_DOWN)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
					break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
				if (netif_running(adapter->netdev))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
					e1000_reinit_locked(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
				else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
					e1000_reset(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
				break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
			}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
		return -EOPNOTSUPP;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
	return E1000_SUCCESS;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
e1000_pci_set_mwi(struct e1000_hw *hw)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
	struct e1000_adapter *adapter = hw->back;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
	int ret_val = pci_set_mwi(adapter->pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
	if (ret_val)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
		DPRINTK(PROBE, ERR, "Error in setting MWI\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
e1000_pci_clear_mwi(struct e1000_hw *hw)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
	struct e1000_adapter *adapter = hw->back;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
	pci_clear_mwi(adapter->pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	struct e1000_adapter *adapter = hw->back;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
	pci_read_config_word(adapter->pdev, reg, value);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
	struct e1000_adapter *adapter = hw->back;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
	pci_write_config_word(adapter->pdev, reg, *value);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
#if 0
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
uint32_t
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
e1000_io_read(struct e1000_hw *hw, unsigned long port)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	return inl(port);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
#endif  /*  0  */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
	outl(value, port);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
	uint32_t ctrl, rctl;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
	e1000_irq_disable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
	adapter->vlgrp = grp;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	if (grp) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
		/* enable VLAN tag insert/strip */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
		ctrl = E1000_READ_REG(&adapter->hw, CTRL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
		ctrl |= E1000_CTRL_VME;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
		if (adapter->hw.mac_type != e1000_ich8lan) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
		/* enable VLAN receive filtering */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
		rctl = E1000_READ_REG(&adapter->hw, RCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
		rctl |= E1000_RCTL_VFE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		rctl &= ~E1000_RCTL_CFIEN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
		E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		e1000_update_mng_vlan(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
	} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
		/* disable VLAN tag insert/strip */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
		ctrl = E1000_READ_REG(&adapter->hw, CTRL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
		ctrl &= ~E1000_CTRL_VME;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		if (adapter->hw.mac_type != e1000_ich8lan) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
		/* disable VLAN filtering */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
		rctl = E1000_READ_REG(&adapter->hw, RCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
		rctl &= ~E1000_RCTL_VFE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
		E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
		if (adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
	e1000_irq_enable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	uint32_t vfta, index;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
	if ((adapter->hw.mng_cookie.status &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	    (vid == adapter->mng_vlan_id))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
	/* add VID to filter table */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	index = (vid >> 5) & 0x7F;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	vfta |= (1 << (vid & 0x1F));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
	e1000_write_vfta(&adapter->hw, index, vfta);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
	uint32_t vfta, index;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
	e1000_irq_disable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
	if (adapter->vlgrp)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
		adapter->vlgrp->vlan_devices[vid] = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
	e1000_irq_enable(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
	if ((adapter->hw.mng_cookie.status &
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	    (vid == adapter->mng_vlan_id)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
		/* release control to f/w */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
		e1000_release_hw_control(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
		return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	/* remove VID from filter table */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
	index = (vid >> 5) & 0x7F;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
	vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
	vfta &= ~(1 << (vid & 0x1F));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
	e1000_write_vfta(&adapter->hw, index, vfta);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
e1000_restore_vlan(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
	if (adapter->vlgrp) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		uint16_t vid;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
			if (!adapter->vlgrp->vlan_devices[vid])
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
				continue;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
	adapter->hw.autoneg = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
	/* Fiber NICs only allow 1000 gbps Full duplex */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
	if ((adapter->hw.media_type == e1000_media_type_fiber) &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		return -EINVAL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
	switch (spddplx) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
	case SPEED_10 + DUPLEX_HALF:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
		adapter->hw.forced_speed_duplex = e1000_10_half;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
	case SPEED_10 + DUPLEX_FULL:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
		adapter->hw.forced_speed_duplex = e1000_10_full;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
	case SPEED_100 + DUPLEX_HALF:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
		adapter->hw.forced_speed_duplex = e1000_100_half;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	case SPEED_100 + DUPLEX_FULL:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
		adapter->hw.forced_speed_duplex = e1000_100_full;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
	case SPEED_1000 + DUPLEX_FULL:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
		adapter->hw.autoneg = 1;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
		adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
		return -EINVAL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
#ifdef CONFIG_PM
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
/* Save/restore 16 or 64 dwords of PCI config space depending on which
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
 * bus we're on (PCI(X) vs. PCI-E)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
#define PCIE_CONFIG_SPACE_LEN 256
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
#define PCI_CONFIG_SPACE_LEN 64
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
e1000_pci_save_state(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
	struct pci_dev *dev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
	int size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
	if (adapter->hw.mac_type >= e1000_82571)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
		size = PCIE_CONFIG_SPACE_LEN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
		size = PCI_CONFIG_SPACE_LEN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	WARN_ON(adapter->config_space != NULL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	adapter->config_space = kmalloc(size, GFP_KERNEL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	if (!adapter->config_space) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
		DPRINTK(PROBE, ERR, "unable to allocate %d bytes\n", size);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
		return -ENOMEM;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	for (i = 0; i < (size / 4); i++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
		pci_read_config_dword(dev, i * 4, &adapter->config_space[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
e1000_pci_restore_state(struct e1000_adapter *adapter)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	struct pci_dev *dev = adapter->pdev;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
	int size;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
	int i;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	if (adapter->config_space == NULL)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
		return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	if (adapter->hw.mac_type >= e1000_82571)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
		size = PCIE_CONFIG_SPACE_LEN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	else
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
		size = PCI_CONFIG_SPACE_LEN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	for (i = 0; i < (size / 4); i++)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		pci_write_config_dword(dev, i * 4, adapter->config_space[i]);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	kfree(adapter->config_space);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
	adapter->config_space = NULL;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
	return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
#endif /* CONFIG_PM */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
e1000_suspend(struct pci_dev *pdev, pm_message_t state)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	struct net_device *netdev = pci_get_drvdata(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	uint32_t ctrl, ctrl_ext, rctl, manc, status;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	uint32_t wufc = adapter->wol;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
#ifdef CONFIG_PM
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	int retval = 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
	netif_device_detach(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	if (netif_running(netdev)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
		e1000_down(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
#ifdef CONFIG_PM
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	/* Implement our own version of pci_save_state(pdev) because pci-
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	 * express adapters have 256-byte config spaces. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
	retval = e1000_pci_save_state(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	if (retval)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
		return retval;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	status = E1000_READ_REG(&adapter->hw, STATUS);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	if (status & E1000_STATUS_LU)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
		wufc &= ~E1000_WUFC_LNKC;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
	if (wufc) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
		e1000_setup_rctl(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
		e1000_set_multi(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
		/* turn on all-multi mode if wake on multicast is enabled */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
		if (adapter->wol & E1000_WUFC_MC) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
			rctl = E1000_READ_REG(&adapter->hw, RCTL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
			rctl |= E1000_RCTL_MPE;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
		if (adapter->hw.mac_type >= e1000_82540) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
			ctrl = E1000_READ_REG(&adapter->hw, CTRL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
			/* advertise wake from D3Cold */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
			#define E1000_CTRL_ADVD3WUC 0x00100000
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
			/* phy power management enable */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
			ctrl |= E1000_CTRL_ADVD3WUC |
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
				E1000_CTRL_EN_PHY_PWR_MGMT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
			E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
		if (adapter->hw.media_type == e1000_media_type_fiber ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
		   adapter->hw.media_type == e1000_media_type_internal_serdes) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
			/* keep the laser running in D3 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
			ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
			E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
		/* Allow time for pending master requests to run */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
		e1000_disable_pciex_master(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
		E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
		E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
		pci_enable_wake(pdev, PCI_D3hot, 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
		pci_enable_wake(pdev, PCI_D3cold, 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
	} else {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
		E1000_WRITE_REG(&adapter->hw, WUC, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
		E1000_WRITE_REG(&adapter->hw, WUFC, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
		pci_enable_wake(pdev, PCI_D3hot, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
		pci_enable_wake(pdev, PCI_D3cold, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	/* FIXME: this code is incorrect for PCI Express */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
	if (adapter->hw.mac_type >= e1000_82540 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	   adapter->hw.mac_type != e1000_ich8lan &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
	   adapter->hw.media_type == e1000_media_type_copper) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
		manc = E1000_READ_REG(&adapter->hw, MANC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
		if (manc & E1000_MANC_SMBUS_EN) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
			manc |= E1000_MANC_ARP_EN;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
			E1000_WRITE_REG(&adapter->hw, MANC, manc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
			pci_enable_wake(pdev, PCI_D3hot, 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
			pci_enable_wake(pdev, PCI_D3cold, 1);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	if (adapter->hw.phy_type == e1000_phy_igp_3)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
		e1000_phy_powerdown_workaround(&adapter->hw);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
	if (netif_running(netdev))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
		e1000_free_irq(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
	 * would have already happened in close and is redundant. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
	e1000_release_hw_control(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
	pci_disable_device(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	pci_set_power_state(pdev, pci_choose_state(pdev, state));
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
#ifdef CONFIG_PM
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
static int
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
e1000_resume(struct pci_dev *pdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	struct net_device *netdev = pci_get_drvdata(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	uint32_t manc, ret_val;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	pci_set_power_state(pdev, PCI_D0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	e1000_pci_restore_state(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	ret_val = pci_enable_device(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	pci_set_master(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	pci_enable_wake(pdev, PCI_D3hot, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	pci_enable_wake(pdev, PCI_D3cold, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
	if (netif_running(netdev) && (ret_val = e1000_request_irq(adapter)))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
		return ret_val;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
	e1000_power_up_phy(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	e1000_reset(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	E1000_WRITE_REG(&adapter->hw, WUS, ~0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	if (netif_running(netdev))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
		e1000_up(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
	netif_device_attach(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
	/* FIXME: this code is incorrect for PCI Express */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	if (adapter->hw.mac_type >= e1000_82540 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	   adapter->hw.mac_type != e1000_ich8lan &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
	   adapter->hw.media_type == e1000_media_type_copper) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		manc = E1000_READ_REG(&adapter->hw, MANC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
		manc &= ~(E1000_MANC_ARP_EN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
		E1000_WRITE_REG(&adapter->hw, MANC, manc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	/* If the controller is 82573 and f/w is AMT, do not set
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	 * DRV_LOAD until the interface is up.  For all other cases,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	 * let the f/w know that the h/w is now under the control
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	 * of the driver. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	if (adapter->hw.mac_type != e1000_82573 ||
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	    !e1000_check_mng_mode(&adapter->hw))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
		e1000_get_hw_control(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	return 0;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
static void e1000_shutdown(struct pci_dev *pdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	e1000_suspend(pdev, PMSG_SUSPEND);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
#ifdef CONFIG_NET_POLL_CONTROLLER
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
/*
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
 * Polling 'interrupt' - used by things like netconsole to send skbs
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
 * without having to re-enable interrupts. It's not called while
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
 * the interrupt routine is executing.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
static void
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
e1000_netpoll(struct net_device *netdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
	struct e1000_adapter *adapter = netdev_priv(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
	disable_irq(adapter->pdev->irq);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	e1000_intr(adapter->pdev->irq, netdev, NULL);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
	e1000_clean_tx_irq(adapter, adapter->tx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
#ifndef CONFIG_E1000_NAPI
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	adapter->clean_rx(adapter, adapter->rx_ring);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	enable_irq(adapter->pdev->irq);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
#endif
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
 * e1000_io_error_detected - called when PCI error is detected
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
 * @pdev: Pointer to PCI device
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
 * @state: The current pci conneection state
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
 * This function is called after a PCI bus error affecting
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
 * this device has been detected.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
	struct net_device *netdev = pci_get_drvdata(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
	struct e1000_adapter *adapter = netdev->priv;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
	netif_device_detach(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
	if (netif_running(netdev))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
		e1000_down(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
	/* Request a slot slot reset. */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
	return PCI_ERS_RESULT_NEED_RESET;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
 * e1000_io_slot_reset - called after the pci bus has been reset.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
 * @pdev: Pointer to PCI device
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
 * Restart the card from scratch, as if from a cold-boot. Implementation
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
 * resembles the first-half of the e1000_resume routine.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
	struct net_device *netdev = pci_get_drvdata(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	struct e1000_adapter *adapter = netdev->priv;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	if (pci_enable_device(pdev)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
		printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
		return PCI_ERS_RESULT_DISCONNECT;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
	pci_set_master(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
	pci_enable_wake(pdev, 3, 0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
	pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	/* Perform card reset only on one instance of the card */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
	if (PCI_FUNC (pdev->devfn) != 0)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
		return PCI_ERS_RESULT_RECOVERED;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
	e1000_reset(adapter);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	E1000_WRITE_REG(&adapter->hw, WUS, ~0);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	return PCI_ERS_RESULT_RECOVERED;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
/**
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
 * e1000_io_resume - called when traffic can start flowing again.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
 * @pdev: Pointer to PCI device
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
 *
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
 * This callback is called when the error recovery driver tells us that
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
 * its OK to resume normal operation. Implementation resembles the
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
 * second-half of the e1000_resume routine.
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
 */
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
static void e1000_io_resume(struct pci_dev *pdev)
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
{
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
	struct net_device *netdev = pci_get_drvdata(pdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
	struct e1000_adapter *adapter = netdev->priv;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
	uint32_t manc, swsm;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
	if (netif_running(netdev)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
		if (e1000_up(adapter)) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
			printk("e1000: can't bring device back up after reset\n");
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
			return;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
		}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	netif_device_attach(netdev);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
	if (adapter->hw.mac_type >= e1000_82540 &&
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
	    adapter->hw.media_type == e1000_media_type_copper) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
		manc = E1000_READ_REG(&adapter->hw, MANC);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
		manc &= ~(E1000_MANC_ARP_EN);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
		E1000_WRITE_REG(&adapter->hw, MANC, manc);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
	switch (adapter->hw.mac_type) {
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
	case e1000_82573:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
		swsm = E1000_READ_REG(&adapter->hw, SWSM);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
		E1000_WRITE_REG(&adapter->hw, SWSM,
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
				swsm | E1000_SWSM_DRV_LOAD);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
	default:
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
		break;
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
	}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
	if (netif_running(netdev))
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
		mod_timer(&adapter->watchdog_timer, jiffies);
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
}
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
9feff35c9617 First version with e1000 driver (to be continued...)
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
/* e1000_main.c */