devices/e100-2.6.31-ethercat.c
author Gavin Lambert <gavinl@compacsort.com>
Tue, 14 Apr 2015 09:33:24 -0400
changeset 2618 3affe9cd0b66
parent 2589 2b9c78543663
permissions -rw-r--r--
Ignore NXIO error otherwise this causes spam if network is empty or refclk not
selected yet, and syncing refclk time to master.
1812
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/******************************************************************************
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
 *  $Id$
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
 *  Copyright (C) 2007-2008  Florian Pose, Ingenieurgemeinschaft IgH
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
 *  This file is part of the IgH EtherCAT Master.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
 *  modify it under the terms of the GNU General Public License version 2, as
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
 *  published by the Free Software Foundation.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
 *  Public License for more details.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
 *  You should have received a copy of the GNU General Public License along
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
 *  with the IgH EtherCAT Master; if not, write to the Free Software
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
 *  ---
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
 *  The license mentioned above concerns the source code only. Using the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
 *  EtherCAT technology and brand is only permitted in compliance with the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
 *  industrial property and similar rights of Beckhoff Automation GmbH.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
 *  ---
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
 *  vim: noexpandtab
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
 *****************************************************************************/
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
/**
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
   \file
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
   EtherCAT driver for e100-compatible NICs.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
*/
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
/* Former documentation: */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
/*******************************************************************************
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
  Intel PRO/100 Linux driver
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
  Copyright(c) 1999 - 2006 Intel Corporation.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
  This program is free software; you can redistribute it and/or modify it
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
  under the terms and conditions of the GNU General Public License,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
  version 2, as published by the Free Software Foundation.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
  This program is distributed in the hope it will be useful, but WITHOUT
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
  more details.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
  You should have received a copy of the GNU General Public License along with
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
  this program; if not, write to the Free Software Foundation, Inc.,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
  The full GNU General Public License is included in this distribution in
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
  the file called "COPYING".
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
  Contact Information:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
  Linux NICS <linux.nics@intel.com>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
*******************************************************************************/
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
/*
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
 *	e100.c: Intel(R) PRO/100 ethernet driver
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
 *	(Re)written 2003 by scott.feldman@intel.com.  Based loosely on
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
 *	original e100 driver, but better described as a munging of
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
 *	e100, e1000, eepro100, tg3, 8139cp, and other drivers.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
 *	References:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
 *		Intel 8255x 10/100 Mbps Ethernet Controller Family,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
 *		Open Source Software Developers Manual,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
 *		http://sourceforge.net/projects/e1000
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
 *	                      Theory of Operation
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
 *	I.   General
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
 *	The driver supports Intel(R) 10/100 Mbps PCI Fast Ethernet
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
 *	controller family, which includes the 82557, 82558, 82559, 82550,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
 *	82551, and 82562 devices.  82558 and greater controllers
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
 *	integrate the Intel 82555 PHY.  The controllers are used in
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
 *	server and client network interface cards, as well as in
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
 *	LAN-On-Motherboard (LOM), CardBus, MiniPCI, and ICHx
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
 *	configurations.  8255x supports a 32-bit linear addressing
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
 *	mode and operates at 33Mhz PCI clock rate.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
 *	II.  Driver Operation
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
 *	Memory-mapped mode is used exclusively to access the device's
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
 *	shared-memory structure, the Control/Status Registers (CSR). All
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
 *	setup, configuration, and control of the device, including queuing
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
 *	of Tx, Rx, and configuration commands is through the CSR.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
 *	cmd_lock serializes accesses to the CSR command register.  cb_lock
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
 *	protects the shared Command Block List (CBL).
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
 *	8255x is highly MII-compliant and all access to the PHY go
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
 *	through the Management Data Interface (MDI).  Consequently, the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
 *	driver leverages the mii.c library shared with other MII-compliant
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
 *	devices.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
 *	Big- and Little-Endian byte order as well as 32- and 64-bit
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
 *	archs are supported.  Weak-ordered memory and non-cache-coherent
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
 *	archs are supported.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
 *	III. Transmit
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
 *	A Tx skb is mapped and hangs off of a TCB.  TCBs are linked
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
 *	together in a fixed-size ring (CBL) thus forming the flexible mode
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
 *	memory structure.  A TCB marked with the suspend-bit indicates
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
 *	the end of the ring.  The last TCB processed suspends the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
 *	controller, and the controller can be restarted by issue a CU
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
 *	resume command to continue from the suspend point, or a CU start
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
 *	command to start at a given position in the ring.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
 *	Non-Tx commands (config, multicast setup, etc) are linked
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
 *	into the CBL ring along with Tx commands.  The common structure
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
 *	used for both Tx and non-Tx commands is the Command Block (CB).
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
 *	cb_to_use is the next CB to use for queuing a command; cb_to_clean
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
 *	is the next CB to check for completion; cb_to_send is the first
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
 *	CB to start on in case of a previous failure to resume.  CB clean
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
 *	up happens in interrupt context in response to a CU interrupt.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
 *	cbs_avail keeps track of number of free CB resources available.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
 * 	Hardware padding of short packets to minimum packet size is
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
 * 	enabled.  82557 pads with 7Eh, while the later controllers pad
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
 * 	with 00h.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
 *	IV.  Receive
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
 *	The Receive Frame Area (RFA) comprises a ring of Receive Frame
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
 *	Descriptors (RFD) + data buffer, thus forming the simplified mode
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
 *	memory structure.  Rx skbs are allocated to contain both the RFD
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
 *	and the data buffer, but the RFD is pulled off before the skb is
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
 *	indicated.  The data buffer is aligned such that encapsulated
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
 *	protocol headers are u32-aligned.  Since the RFD is part of the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
 *	mapped shared memory, and completion status is contained within
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
 *	the RFD, the RFD must be dma_sync'ed to maintain a consistent
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
 *	view from software and hardware.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
 *	In order to keep updates to the RFD link field from colliding with
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
 *	hardware writes to mark packets complete, we use the feature that
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
 *	hardware will not write to a size 0 descriptor and mark the previous
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
 *	packet as end-of-list (EL).   After updating the link, we remove EL
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
 *	and only then restore the size such that hardware may use the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
 *	previous-to-end RFD.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
 *	Under typical operation, the  receive unit (RU) is start once,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
 *	and the controller happily fills RFDs as frames arrive.  If
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
 *	replacement RFDs cannot be allocated, or the RU goes non-active,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
 *	the RU must be restarted.  Frame arrival generates an interrupt,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
 *	and Rx indication and re-allocation happen in the same context,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
 *	therefore no locking is required.  A software-generated interrupt
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
 *	is generated from the watchdog to recover from a failed allocation
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
 *	scenario where all Rx resources have been indicated and none re-
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
 *	placed.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
 *	V.   Miscellaneous
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
 * 	VLAN offloading of tagging, stripping and filtering is not
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
 * 	supported, but driver will accommodate the extra 4-byte VLAN tag
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
 * 	for processing by upper layers.  Tx/Rx Checksum offloading is not
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
 * 	supported.  Tx Scatter/Gather is not supported.  Jumbo Frames is
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
 * 	not supported (hardware limitation).
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
 * 	MagicPacket(tm) WoL support is enabled/disabled via ethtool.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
 * 	Thanks to JC (jchapman@katalix.com) for helping with
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
 * 	testing/troubleshooting the development driver.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
 * 	TODO:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
 * 	o several entry points race with dev->close
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
 * 	o check for tx-no-resources/stop Q races with tx clean/wake Q
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
 *	FIXES:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
 * 2005/12/02 - Michael O'Donnell <Michael.ODonnell at stratus dot com>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
 *	- Stratus87247: protect MDI control register manipulations
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
 * 2009/06/01 - Andreas Mohr <andi at lisas dot de>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
 *      - add clean lowlevel I/O emulation for cards with MII-lacking PHYs
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
#include <linux/module.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
#include <linux/moduleparam.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
#include <linux/kernel.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
#include <linux/types.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
#include <linux/slab.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
#include <linux/delay.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
#include <linux/init.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
#include <linux/pci.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
#include <linux/dma-mapping.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
#include <linux/netdevice.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
#include <linux/etherdevice.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
#include <linux/mii.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
#include <linux/if_vlan.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
#include <linux/skbuff.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
#include <linux/ethtool.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
#include <linux/string.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
#include <linux/firmware.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
// EtherCAT includes
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
#include "../globals.h"
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
#include "ecdev.h"
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
#define DRV_NAME		"ec_e100"
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
#include <asm/unaligned.h>
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
#define DRV_EXT			"-NAPI"
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
#define DRV_VERSION		"3.5.24-k2"DRV_EXT
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
#define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
#define DRV_COPYRIGHT		"Copyright(c) 1999-2006 Intel Corporation"
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
#define PFX			DRV_NAME ": "
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
#define E100_WATCHDOG_PERIOD	(2 * HZ)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
#define E100_NAPI_WEIGHT	16
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
#define FIRMWARE_D101M		"e100/d101m_ucode.bin"
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
#define FIRMWARE_D101S		"e100/d101s_ucode.bin"
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
#define FIRMWARE_D102E		"e100/d102e_ucode.bin"
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
MODULE_DESCRIPTION(DRV_DESCRIPTION);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
MODULE_AUTHOR(DRV_COPYRIGHT);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
MODULE_LICENSE("GPL");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
MODULE_VERSION(DRV_VERSION);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
MODULE_FIRMWARE(FIRMWARE_D101M);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
MODULE_FIRMWARE(FIRMWARE_D101S);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
MODULE_FIRMWARE(FIRMWARE_D102E);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
MODULE_DESCRIPTION(DRV_DESCRIPTION);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
MODULE_LICENSE("GPL");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
MODULE_VERSION(DRV_VERSION ", master " EC_MASTER_VERSION);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
void e100_ec_poll(struct net_device *);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
static int debug = 3;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
static int eeprom_bad_csum_allow = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
static int use_io = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
module_param(debug, int, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
module_param(eeprom_bad_csum_allow, int, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
module_param(use_io, int, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
MODULE_PARM_DESC(eeprom_bad_csum_allow, "Allow bad eeprom checksums");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
MODULE_PARM_DESC(use_io, "Force use of i/o access mode");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
#define DPRINTK(nlevel, klevel, fmt, args...) \
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	(void)((NETIF_MSG_##nlevel & nic->msg_enable) && \
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
		__func__ , ## args))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
#define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	PCI_CLASS_NETWORK_ETHERNET << 8, 0xFFFF00, ich }
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
static struct pci_device_id e100_id_table[] = {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	INTEL_8255X_ETHERNET_DEVICE(0x1029, 0),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	INTEL_8255X_ETHERNET_DEVICE(0x1030, 0),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	INTEL_8255X_ETHERNET_DEVICE(0x1031, 3),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	INTEL_8255X_ETHERNET_DEVICE(0x1032, 3),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	INTEL_8255X_ETHERNET_DEVICE(0x1033, 3),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	INTEL_8255X_ETHERNET_DEVICE(0x1034, 3),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	INTEL_8255X_ETHERNET_DEVICE(0x1038, 3),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	INTEL_8255X_ETHERNET_DEVICE(0x1039, 4),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	INTEL_8255X_ETHERNET_DEVICE(0x103A, 4),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	INTEL_8255X_ETHERNET_DEVICE(0x103B, 4),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	INTEL_8255X_ETHERNET_DEVICE(0x103C, 4),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	INTEL_8255X_ETHERNET_DEVICE(0x103D, 4),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	INTEL_8255X_ETHERNET_DEVICE(0x103E, 4),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	INTEL_8255X_ETHERNET_DEVICE(0x1050, 5),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	INTEL_8255X_ETHERNET_DEVICE(0x1051, 5),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	INTEL_8255X_ETHERNET_DEVICE(0x1052, 5),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	INTEL_8255X_ETHERNET_DEVICE(0x1053, 5),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	INTEL_8255X_ETHERNET_DEVICE(0x1054, 5),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	INTEL_8255X_ETHERNET_DEVICE(0x1055, 5),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	INTEL_8255X_ETHERNET_DEVICE(0x1056, 5),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	INTEL_8255X_ETHERNET_DEVICE(0x1057, 5),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	INTEL_8255X_ETHERNET_DEVICE(0x1059, 0),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	INTEL_8255X_ETHERNET_DEVICE(0x1064, 6),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	INTEL_8255X_ETHERNET_DEVICE(0x1065, 6),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	INTEL_8255X_ETHERNET_DEVICE(0x1066, 6),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	INTEL_8255X_ETHERNET_DEVICE(0x1067, 6),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	INTEL_8255X_ETHERNET_DEVICE(0x1068, 6),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	INTEL_8255X_ETHERNET_DEVICE(0x1069, 6),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	INTEL_8255X_ETHERNET_DEVICE(0x106A, 6),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	INTEL_8255X_ETHERNET_DEVICE(0x106B, 6),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	INTEL_8255X_ETHERNET_DEVICE(0x1091, 7),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	INTEL_8255X_ETHERNET_DEVICE(0x1092, 7),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	INTEL_8255X_ETHERNET_DEVICE(0x1093, 7),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	INTEL_8255X_ETHERNET_DEVICE(0x1094, 7),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	INTEL_8255X_ETHERNET_DEVICE(0x1095, 7),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	INTEL_8255X_ETHERNET_DEVICE(0x10fe, 7),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	INTEL_8255X_ETHERNET_DEVICE(0x2459, 2),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	INTEL_8255X_ETHERNET_DEVICE(0x245D, 2),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	INTEL_8255X_ETHERNET_DEVICE(0x27DC, 7),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	{ 0, }
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
// prevent from being loaded automatically
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
//MODULE_DEVICE_TABLE(pci, e100_id_table);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
enum mac {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	mac_82557_D100_A  = 0,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	mac_82557_D100_B  = 1,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	mac_82557_D100_C  = 2,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	mac_82558_D101_A4 = 4,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	mac_82558_D101_B0 = 5,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	mac_82559_D101M   = 8,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	mac_82559_D101S   = 9,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	mac_82550_D102    = 12,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	mac_82550_D102_C  = 13,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	mac_82551_E       = 14,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	mac_82551_F       = 15,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	mac_82551_10      = 16,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	mac_unknown       = 0xFF,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
enum phy {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	phy_100a     = 0x000003E0,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	phy_100c     = 0x035002A8,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	phy_82555_tx = 0x015002A8,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	phy_nsc_tx   = 0x5C002000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	phy_82562_et = 0x033002A8,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	phy_82562_em = 0x032002A8,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	phy_82562_ek = 0x031002A8,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
	phy_82562_eh = 0x017002A8,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	phy_82552_v  = 0xd061004d,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	phy_unknown  = 0xFFFFFFFF,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
/* CSR (Control/Status Registers) */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
struct csr {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	struct {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
		u8 status;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		u8 stat_ack;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		u8 cmd_lo;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
		u8 cmd_hi;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		u32 gen_ptr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
	} scb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	u32 port;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	u16 flash_ctrl;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	u8 eeprom_ctrl_lo;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	u8 eeprom_ctrl_hi;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
	u32 mdi_ctrl;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	u32 rx_dma_count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
enum scb_status {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	rus_no_res       = 0x08,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
	rus_ready        = 0x10,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
	rus_mask         = 0x3C,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
enum ru_state  {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
	RU_SUSPENDED = 0,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	RU_RUNNING	 = 1,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	RU_UNINITIALIZED = -1,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
enum scb_stat_ack {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	stat_ack_not_ours    = 0x00,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	stat_ack_sw_gen      = 0x04,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	stat_ack_rnr         = 0x10,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	stat_ack_cu_idle     = 0x20,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	stat_ack_frame_rx    = 0x40,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	stat_ack_cu_cmd_done = 0x80,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	stat_ack_not_present = 0xFF,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
	stat_ack_rx = (stat_ack_sw_gen | stat_ack_rnr | stat_ack_frame_rx),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
	stat_ack_tx = (stat_ack_cu_idle | stat_ack_cu_cmd_done),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
enum scb_cmd_hi {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	irq_mask_none = 0x00,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
	irq_mask_all  = 0x01,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
	irq_sw_gen    = 0x02,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
enum scb_cmd_lo {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	cuc_nop        = 0x00,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	ruc_start      = 0x01,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	ruc_load_base  = 0x06,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	cuc_start      = 0x10,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	cuc_resume     = 0x20,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	cuc_dump_addr  = 0x40,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	cuc_dump_stats = 0x50,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	cuc_load_base  = 0x60,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	cuc_dump_reset = 0x70,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
enum cuc_dump {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	cuc_dump_complete       = 0x0000A005,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	cuc_dump_reset_complete = 0x0000A007,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
enum port {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	software_reset  = 0x0000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
	selftest        = 0x0001,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	selective_reset = 0x0002,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
enum eeprom_ctrl_lo {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	eesk = 0x01,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	eecs = 0x02,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	eedi = 0x04,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	eedo = 0x08,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
enum mdi_ctrl {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	mdi_write = 0x04000000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	mdi_read  = 0x08000000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	mdi_ready = 0x10000000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
enum eeprom_op {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
	op_write = 0x05,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	op_read  = 0x06,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	op_ewds  = 0x10,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	op_ewen  = 0x13,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
enum eeprom_offsets {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	eeprom_cnfg_mdix  = 0x03,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	eeprom_phy_iface  = 0x06,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	eeprom_id         = 0x0A,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	eeprom_config_asf = 0x0D,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	eeprom_smbus_addr = 0x90,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
enum eeprom_cnfg_mdix {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
	eeprom_mdix_enabled = 0x0080,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
enum eeprom_phy_iface {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	NoSuchPhy = 0,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	I82553AB,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	I82553C,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	I82503,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	DP83840,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	S80C240,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	S80C24,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	I82555,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	DP83840A = 10,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
enum eeprom_id {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	eeprom_id_wol = 0x0020,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
enum eeprom_config_asf {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	eeprom_asf = 0x8000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	eeprom_gcl = 0x4000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
enum cb_status {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	cb_complete = 0x8000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	cb_ok       = 0x2000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
enum cb_command {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	cb_nop    = 0x0000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	cb_iaaddr = 0x0001,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	cb_config = 0x0002,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	cb_multi  = 0x0003,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	cb_tx     = 0x0004,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	cb_ucode  = 0x0005,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
	cb_dump   = 0x0006,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	cb_tx_sf  = 0x0008,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	cb_cid    = 0x1f00,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	cb_i      = 0x2000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
	cb_s      = 0x4000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	cb_el     = 0x8000,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
struct rfd {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	__le16 status;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	__le16 command;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	__le32 link;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	__le32 rbd;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	__le16 actual_size;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	__le16 size;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
struct rx {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	struct rx *next, *prev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	struct sk_buff *skb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	dma_addr_t dma_addr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
#if defined(__BIG_ENDIAN_BITFIELD)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
#define X(a,b)	b,a
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
#else
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
#define X(a,b)	a,b
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
#endif
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
struct config {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
/*0*/	u8 X(byte_count:6, pad0:2);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
/*1*/	u8 X(X(rx_fifo_limit:4, tx_fifo_limit:3), pad1:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
/*2*/	u8 adaptive_ifs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
/*3*/	u8 X(X(X(X(mwi_enable:1, type_enable:1), read_align_enable:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	   term_write_cache_line:1), pad3:4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
/*4*/	u8 X(rx_dma_max_count:7, pad4:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
/*5*/	u8 X(tx_dma_max_count:7, dma_max_count_enable:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
/*6*/	u8 X(X(X(X(X(X(X(late_scb_update:1, direct_rx_dma:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	   tno_intr:1), cna_intr:1), standard_tcb:1), standard_stat_counter:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
	   rx_discard_overruns:1), rx_save_bad_frames:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
/*7*/	u8 X(X(X(X(X(rx_discard_short_frames:1, tx_underrun_retry:2),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	   pad7:2), rx_extended_rfd:1), tx_two_frames_in_fifo:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	   tx_dynamic_tbd:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
/*8*/	u8 X(X(mii_mode:1, pad8:6), csma_disabled:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
/*9*/	u8 X(X(X(X(X(rx_tcpudp_checksum:1, pad9:3), vlan_arp_tco:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	   link_status_wake:1), arp_wake:1), mcmatch_wake:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
/*10*/	u8 X(X(X(pad10:3, no_source_addr_insertion:1), preamble_length:2),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	   loopback:2);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
/*11*/	u8 X(linear_priority:3, pad11:5);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
/*12*/	u8 X(X(linear_priority_mode:1, pad12:3), ifs:4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
/*13*/	u8 ip_addr_lo;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
/*14*/	u8 ip_addr_hi;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
/*15*/	u8 X(X(X(X(X(X(X(promiscuous_mode:1, broadcast_disabled:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	   wait_after_win:1), pad15_1:1), ignore_ul_bit:1), crc_16_bit:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	   pad15_2:1), crs_or_cdt:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
/*16*/	u8 fc_delay_lo;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
/*17*/	u8 fc_delay_hi;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
/*18*/	u8 X(X(X(X(X(rx_stripping:1, tx_padding:1), rx_crc_transfer:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	   rx_long_ok:1), fc_priority_threshold:3), pad18:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
/*19*/	u8 X(X(X(X(X(X(X(addr_wake:1, magic_packet_disable:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	   fc_disable:1), fc_restop:1), fc_restart:1), fc_reject:1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	   full_duplex_force:1), full_duplex_pin:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
/*20*/	u8 X(X(X(pad20_1:5, fc_priority_location:1), multi_ia:1), pad20_2:1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
/*21*/	u8 X(X(pad21_1:3, multicast_all:1), pad21_2:4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
/*22*/	u8 X(X(rx_d102_mode:1, rx_vlan_drop:1), pad22:6);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	u8 pad_d102[9];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
#define E100_MAX_MULTICAST_ADDRS	64
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
struct multi {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	__le16 count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	u8 addr[E100_MAX_MULTICAST_ADDRS * ETH_ALEN + 2/*pad*/];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
/* Important: keep total struct u32-aligned */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
#define UCODE_SIZE			134
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
struct cb {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	__le16 status;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
	__le16 command;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	__le32 link;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	union {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
		u8 iaaddr[ETH_ALEN];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
		__le32 ucode[UCODE_SIZE];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
		struct config config;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		struct multi multi;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		struct {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
			u32 tbd_array;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
			u16 tcb_byte_count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
			u8 threshold;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
			u8 tbd_count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
			struct {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
				__le32 buf_addr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
				__le16 size;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
				u16 eol;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
			} tbd;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
		} tcb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
		__le32 dump_buffer_addr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	} u;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	struct cb *next, *prev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	dma_addr_t dma_addr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	struct sk_buff *skb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
enum loopback {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	lb_none = 0, lb_mac = 1, lb_phy = 3,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
struct stats {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	__le32 tx_good_frames, tx_max_collisions, tx_late_collisions,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
		tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		tx_multiple_collisions, tx_total_collisions;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	__le32 rx_good_frames, rx_crc_errors, rx_alignment_errors,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		rx_resource_errors, rx_overrun_errors, rx_cdt_errors,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		rx_short_frame_errors;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	__le32 fc_xmt_pause, fc_rcv_pause, fc_rcv_unsupported;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	__le16 xmt_tco_frames, rcv_tco_frames;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	__le32 complete;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
struct mem {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	struct {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		u32 signature;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
		u32 result;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	} selftest;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	struct stats stats;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	u8 dump_buf[596];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
struct param_range {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	u32 min;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	u32 max;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	u32 count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
struct params {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	struct param_range rfds;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	struct param_range cbs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
struct nic {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	/* Begin: frequently used values: keep adjacent for cache effect */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	u32 msg_enable				____cacheline_aligned;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	struct net_device *netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
	struct pci_dev *pdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	u16 (*mdio_ctrl)(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	struct rx *rxs				____cacheline_aligned;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	struct rx *rx_to_use;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	struct rx *rx_to_clean;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
	struct rfd blank_rfd;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	enum ru_state ru_running;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	spinlock_t cb_lock			____cacheline_aligned;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	spinlock_t cmd_lock;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	struct csr __iomem *csr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	enum scb_cmd_lo cuc_cmd;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	unsigned int cbs_avail;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	struct napi_struct napi;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	struct cb *cbs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	struct cb *cb_to_use;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	struct cb *cb_to_send;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	struct cb *cb_to_clean;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	__le16 tx_command;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	/* End: frequently used values: keep adjacent for cache effect */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	enum {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
		ich                = (1 << 0),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		promiscuous        = (1 << 1),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
		multicast_all      = (1 << 2),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
		wol_magic          = (1 << 3),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
		ich_10h_workaround = (1 << 4),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	} flags					____cacheline_aligned;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	enum mac mac;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
	enum phy phy;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	struct params params;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	struct timer_list watchdog;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	struct timer_list blink_timer;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	struct mii_if_info mii;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	struct work_struct tx_timeout_task;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	enum loopback loopback;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	struct mem *mem;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	dma_addr_t dma_addr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	dma_addr_t cbs_dma_addr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	u8 adaptive_ifs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
	u8 tx_threshold;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	u32 tx_frames;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	u32 tx_collisions;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	u32 tx_deferred;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	u32 tx_single_collisions;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	u32 tx_multiple_collisions;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	u32 tx_fc_pause;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	u32 tx_tco_frames;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	u32 rx_fc_pause;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
	u32 rx_fc_unsupported;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	u32 rx_tco_frames;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	u32 rx_over_length_errors;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	u16 leds;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	u16 eeprom_wc;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	__le16 eeprom[256];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	spinlock_t mdio_lock;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	ec_device_t *ecdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	unsigned long ec_watchdog_jiffies;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
static inline void e100_write_flush(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	/* Flush previous PCI writes through intermediate bridges
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	 * by doing a benign read */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	(void)ioread8(&nic->csr->scb.status);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
static void e100_enable_irq(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	unsigned long flags;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	if (nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
		return;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	spin_lock_irqsave(&nic->cmd_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	iowrite8(irq_mask_none, &nic->csr->scb.cmd_hi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
	e100_write_flush(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	spin_unlock_irqrestore(&nic->cmd_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
static void e100_disable_irq(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
{
1928
e9d5929829ba Fixed compiler warning.
Florian Pose <fp@igh-essen.com>
parents: 1812
diff changeset
   707
	unsigned long flags = 0;
1812
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
		spin_lock_irqsave(&nic->cmd_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	iowrite8(irq_mask_all, &nic->csr->scb.cmd_hi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	e100_write_flush(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
		spin_unlock_irqrestore(&nic->cmd_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
static void e100_hw_reset(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	/* Put CU and RU into idle with a selective reset to get
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	 * device off of PCI bus */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	iowrite32(selective_reset, &nic->csr->port);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	e100_write_flush(nic); udelay(20);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	/* Now fully reset device */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	iowrite32(software_reset, &nic->csr->port);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	e100_write_flush(nic); udelay(20);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	/* Mask off our interrupt line - it's unmasked after reset */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	e100_disable_irq(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
static int e100_self_test(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	u32 dma_addr = nic->dma_addr + offsetof(struct mem, selftest);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	/* Passing the self-test is a pretty good indication
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	 * that the device can DMA to/from host memory */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	nic->mem->selftest.signature = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	nic->mem->selftest.result = 0xFFFFFFFF;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	iowrite32(selftest | dma_addr, &nic->csr->port);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	e100_write_flush(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	/* Wait 10 msec for self-test to complete */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	msleep(10);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	/* Interrupts are enabled after self-test */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	e100_disable_irq(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	/* Check results of self-test */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	if (nic->mem->selftest.result != 0) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
		DPRINTK(HW, ERR, "Self-test failed: result=0x%08X\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
			nic->mem->selftest.result);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
		return -ETIMEDOUT;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	if (nic->mem->selftest.signature == 0) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
		DPRINTK(HW, ERR, "Self-test failed: timed out\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
		return -ETIMEDOUT;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, __le16 data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	u32 cmd_addr_data[3];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	u8 ctrl;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	int i, j;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	/* Three cmds: write/erase enable, write data, write/erase disable */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	cmd_addr_data[0] = op_ewen << (addr_len - 2);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	cmd_addr_data[1] = (((op_write << addr_len) | addr) << 16) |
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		le16_to_cpu(data);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	cmd_addr_data[2] = op_ewds << (addr_len - 2);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	/* Bit-bang cmds to write word to eeprom */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	for (j = 0; j < 3; j++) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
		/* Chip select */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
		iowrite8(eecs | eesk, &nic->csr->eeprom_ctrl_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
		e100_write_flush(nic); udelay(4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		for (i = 31; i >= 0; i--) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
			ctrl = (cmd_addr_data[j] & (1 << i)) ?
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
				eecs | eedi : eecs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
			iowrite8(ctrl, &nic->csr->eeprom_ctrl_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
			e100_write_flush(nic); udelay(4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
			iowrite8(ctrl | eesk, &nic->csr->eeprom_ctrl_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
			e100_write_flush(nic); udelay(4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
		/* Wait 10 msec for cmd to complete */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
		msleep(10);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
		/* Chip deselect */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		iowrite8(0, &nic->csr->eeprom_ctrl_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
		e100_write_flush(nic); udelay(4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
/* General technique stolen from the eepro100 driver - very clever */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
static __le16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	u32 cmd_addr_data;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	u16 data = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	u8 ctrl;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	int i;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	cmd_addr_data = ((op_read << *addr_len) | addr) << 16;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	/* Chip select */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	iowrite8(eecs | eesk, &nic->csr->eeprom_ctrl_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	e100_write_flush(nic); udelay(4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	/* Bit-bang to read word from eeprom */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
	for (i = 31; i >= 0; i--) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		ctrl = (cmd_addr_data & (1 << i)) ? eecs | eedi : eecs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
		iowrite8(ctrl, &nic->csr->eeprom_ctrl_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
		e100_write_flush(nic); udelay(4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		iowrite8(ctrl | eesk, &nic->csr->eeprom_ctrl_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
		e100_write_flush(nic); udelay(4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
		/* Eeprom drives a dummy zero to EEDO after receiving
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
		 * complete address.  Use this to adjust addr_len. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
		ctrl = ioread8(&nic->csr->eeprom_ctrl_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		if (!(ctrl & eedo) && i > 16) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
			*addr_len -= (i - 16);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
			i = 17;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
		data = (data << 1) | (ctrl & eedo ? 1 : 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	/* Chip deselect */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	iowrite8(0, &nic->csr->eeprom_ctrl_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	e100_write_flush(nic); udelay(4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	return cpu_to_le16(data);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
/* Load entire EEPROM image into driver cache and validate checksum */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
static int e100_eeprom_load(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	u16 addr, addr_len = 8, checksum = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	/* Try reading with an 8-bit addr len to discover actual addr len */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	e100_eeprom_read(nic, &addr_len, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	nic->eeprom_wc = 1 << addr_len;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	for (addr = 0; addr < nic->eeprom_wc; addr++) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
		nic->eeprom[addr] = e100_eeprom_read(nic, &addr_len, addr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
		if (addr < nic->eeprom_wc - 1)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
			checksum += le16_to_cpu(nic->eeprom[addr]);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	/* The checksum, stored in the last word, is calculated such that
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	 * the sum of words should be 0xBABA */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	if (cpu_to_le16(0xBABA - checksum) != nic->eeprom[nic->eeprom_wc - 1]) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
		DPRINTK(PROBE, ERR, "EEPROM corrupted\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		if (!eeprom_bad_csum_allow)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
			return -EAGAIN;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
/* Save (portion of) driver EEPROM cache to device and update checksum */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
static int e100_eeprom_save(struct nic *nic, u16 start, u16 count)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	u16 addr, addr_len = 8, checksum = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	/* Try reading with an 8-bit addr len to discover actual addr len */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	e100_eeprom_read(nic, &addr_len, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	nic->eeprom_wc = 1 << addr_len;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	if (start + count >= nic->eeprom_wc)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		return -EINVAL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	for (addr = start; addr < start + count; addr++)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
		e100_eeprom_write(nic, addr_len, addr, nic->eeprom[addr]);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	/* The checksum, stored in the last word, is calculated such that
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	 * the sum of words should be 0xBABA */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	for (addr = 0; addr < nic->eeprom_wc - 1; addr++)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		checksum += le16_to_cpu(nic->eeprom[addr]);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	nic->eeprom[nic->eeprom_wc - 1] = cpu_to_le16(0xBABA - checksum);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	e100_eeprom_write(nic, addr_len, nic->eeprom_wc - 1,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
		nic->eeprom[nic->eeprom_wc - 1]);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
#define E100_WAIT_SCB_TIMEOUT 20000 /* we might have to wait 100ms!!! */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
#define E100_WAIT_SCB_FAST 20       /* delay like the old code */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
static int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	unsigned long flags = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	unsigned int i;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	int err = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		spin_lock_irqsave(&nic->cmd_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	/* Previous command is accepted when SCB clears */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	for (i = 0; i < E100_WAIT_SCB_TIMEOUT; i++) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
		if (likely(!ioread8(&nic->csr->scb.cmd_lo)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
			break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
		cpu_relax();
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		if (unlikely(i > E100_WAIT_SCB_FAST))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
			udelay(5);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	if (unlikely(i == E100_WAIT_SCB_TIMEOUT)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
		err = -EAGAIN;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
		goto err_unlock;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	if (unlikely(cmd != cuc_resume))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
		iowrite32(dma_addr, &nic->csr->scb.gen_ptr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	iowrite8(cmd, &nic->csr->scb.cmd_lo);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
err_unlock:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		spin_unlock_irqrestore(&nic->cmd_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
static int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	struct cb *cb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	unsigned long flags = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	int err = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		spin_lock_irqsave(&nic->cb_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	if (unlikely(!nic->cbs_avail)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
		err = -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		goto err_unlock;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	cb = nic->cb_to_use;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	nic->cb_to_use = cb->next;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
	nic->cbs_avail--;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	cb->skb = skb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	if (unlikely(!nic->cbs_avail))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
		err = -ENOSPC;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	cb_prepare(nic, cb, skb);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	/* Order is important otherwise we'll be in a race with h/w:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	 * set S-bit in current first, then clear S-bit in previous. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	cb->command |= cpu_to_le16(cb_s);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	wmb();
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	cb->prev->command &= cpu_to_le16(~cb_s);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	while (nic->cb_to_send != nic->cb_to_use) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
		if (unlikely(e100_exec_cmd(nic, nic->cuc_cmd,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
			nic->cb_to_send->dma_addr))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
			/* Ok, here's where things get sticky.  It's
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
			 * possible that we can't schedule the command
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
			 * because the controller is too busy, so
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
			 * let's just queue the command and try again
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
			 * when another command is scheduled. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
			if (err == -ENOSPC) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
				//request a reset
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
				schedule_work(&nic->tx_timeout_task);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
			}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
			break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
			nic->cuc_cmd = cuc_resume;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
			nic->cb_to_send = nic->cb_to_send->next;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
err_unlock:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
		spin_unlock_irqrestore(&nic->cb_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
static int mdio_read(struct net_device *netdev, int addr, int reg)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	return nic->mdio_ctrl(nic, addr, mdi_read, reg, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	nic->mdio_ctrl(nic, addr, mdi_write, reg, data);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
/* the standard mdio_ctrl() function for usual MII-compliant hardware */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	u32 data_out = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	unsigned int i;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	unsigned long flags = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	/*
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	 * Stratus87247: we shouldn't be writing the MDI control
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	 * register until the Ready bit shows True.  Also, since
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	 * manipulation of the MDI control registers is a multi-step
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	 * procedure it should be done under lock.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		spin_lock_irqsave(&nic->mdio_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	for (i = 100; i; --i) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		if (ioread32(&nic->csr->mdi_ctrl) & mdi_ready)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
			break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		udelay(20);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	if (unlikely(!i)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
		printk("e100.mdio_ctrl(%s) won't go Ready\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
			nic->netdev->name );
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
		if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
			spin_unlock_irqrestore(&nic->mdio_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
		return 0;		/* No way to indicate timeout error */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	iowrite32((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	for (i = 0; i < 100; i++) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
		udelay(20);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		if ((data_out = ioread32(&nic->csr->mdi_ctrl)) & mdi_ready)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
			break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		spin_unlock_irqrestore(&nic->mdio_lock, flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	DPRINTK(HW, DEBUG,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		"%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
		dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	return (u16)data_out;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
/* slightly tweaked mdio_ctrl() function for phy_82552_v specifics */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
static u16 mdio_ctrl_phy_82552_v(struct nic *nic,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
				 u32 addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
				 u32 dir,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
				 u32 reg,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
				 u16 data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	if ((reg == MII_BMCR) && (dir == mdi_write)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		if (data & (BMCR_ANRESTART | BMCR_ANENABLE)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
			u16 advert = mdio_read(nic->netdev, nic->mii.phy_id,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
							MII_ADVERTISE);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
			/*
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
			 * Workaround Si issue where sometimes the part will not
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
			 * autoneg to 100Mbps even when advertised.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
			 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
			if (advert & ADVERTISE_100FULL)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
				data |= BMCR_SPEED100 | BMCR_FULLDPLX;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
			else if (advert & ADVERTISE_100HALF)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
				data |= BMCR_SPEED100;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	return mdio_ctrl_hw(nic, addr, dir, reg, data);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
/* Fully software-emulated mdio_ctrl() function for cards without
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
 * MII-compliant PHYs.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
 * For now, this is mainly geared towards 80c24 support; in case of further
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
 * requirements for other types (i82503, ...?) either extend this mechanism
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
 * or split it, whichever is cleaner.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
static u16 mdio_ctrl_phy_mii_emulated(struct nic *nic,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
				      u32 addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
				      u32 dir,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
				      u32 reg,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
				      u16 data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	/* might need to allocate a netdev_priv'ed register array eventually
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	 * to be able to record state changes, but for now
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	 * some fully hardcoded register handling ought to be ok I guess. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	if (dir == mdi_read) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
		switch (reg) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		case MII_BMCR:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
			/* Auto-negotiation, right? */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
			return  BMCR_ANENABLE |
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
				BMCR_FULLDPLX;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		case MII_BMSR:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
			return	BMSR_LSTATUS /* for mii_link_ok() */ |
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
				BMSR_ANEGCAPABLE |
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
				BMSR_10FULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		case MII_ADVERTISE:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
			/* 80c24 is a "combo card" PHY, right? */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
			return	ADVERTISE_10HALF |
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
				ADVERTISE_10FULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		default:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
			DPRINTK(HW, DEBUG,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		"%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
			return 0xFFFF;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		switch (reg) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
		default:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
			DPRINTK(HW, DEBUG,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
		"%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
			return 0xFFFF;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
static inline int e100_phy_supports_mii(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	/* for now, just check it by comparing whether we
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	   are using MII software emulation.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	*/
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	return (nic->mdio_ctrl != mdio_ctrl_phy_mii_emulated);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
static void e100_get_defaults(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
	struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	struct param_range cbs  = { .min = 64, .max = 256, .count = 128 };
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->pdev->revision;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	if (nic->mac == mac_unknown)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		nic->mac = mac_82557_D100_A;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	nic->params.rfds = rfds;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	nic->params.cbs = cbs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
	/* Quadwords to DMA into FIFO before starting frame transmit */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	nic->tx_threshold = 0xE0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
	/* no interrupt for every tx completion, delay = 256us if not 557 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	nic->tx_command = cpu_to_le16(cb_tx | cb_tx_sf |
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	/* Template for a freshly allocated RFD */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	nic->blank_rfd.command = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	nic->blank_rfd.rbd = cpu_to_le32(0xFFFFFFFF);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	/* MII setup */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	nic->mii.phy_id_mask = 0x1F;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	nic->mii.reg_num_mask = 0x1F;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
	nic->mii.dev = nic->netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	nic->mii.mdio_read = mdio_read;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
	nic->mii.mdio_write = mdio_write;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	struct config *config = &cb->u.config;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	u8 *c = (u8 *)config;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	cb->command = cpu_to_le16(cb_config);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	memset(config, 0, sizeof(struct config));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
	config->byte_count = 0x16;		/* bytes in this struct */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	config->rx_fifo_limit = 0x8;		/* bytes in FIFO before DMA */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	config->direct_rx_dma = 0x1;		/* reserved */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	config->standard_tcb = 0x1;		/* 1=standard, 0=extended */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	config->standard_stat_counter = 0x1;	/* 1=standard, 0=extended */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	config->rx_discard_short_frames = 0x1;	/* 1=discard, 0=pass */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	config->tx_underrun_retry = 0x3;	/* # of underrun retries */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	if (e100_phy_supports_mii(nic))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		config->mii_mode = 1;           /* 1=MII mode, 0=i82503 mode */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	config->pad10 = 0x6;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
	config->no_source_addr_insertion = 0x1;	/* 1=no, 0=yes */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	config->preamble_length = 0x2;		/* 0=1, 1=3, 2=7, 3=15 bytes */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	config->ifs = 0x6;			/* x16 = inter frame spacing */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	config->ip_addr_hi = 0xF2;		/* ARP IP filter - not used */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	config->pad15_1 = 0x1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
	config->pad15_2 = 0x1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	config->crs_or_cdt = 0x0;		/* 0=CRS only, 1=CRS or CDT */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	config->fc_delay_hi = 0x40;		/* time delay for fc frame */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	config->tx_padding = 0x1;		/* 1=pad short frames */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	config->fc_priority_threshold = 0x7;	/* 7=priority fc disabled */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	config->pad18 = 0x1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	config->full_duplex_pin = 0x1;		/* 1=examine FDX# pin */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	config->pad20_1 = 0x1F;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	config->fc_priority_location = 0x1;	/* 1=byte#31, 0=byte#19 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	config->pad21_1 = 0x5;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	config->adaptive_ifs = nic->adaptive_ifs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	config->loopback = nic->loopback;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	if (nic->mii.force_media && nic->mii.full_duplex)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		config->full_duplex_force = 0x1;	/* 1=force, 0=auto */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
	if (nic->flags & promiscuous || nic->loopback) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		config->rx_save_bad_frames = 0x1;	/* 1=save, 0=discard */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		config->rx_discard_short_frames = 0x0;	/* 1=discard, 0=save */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		config->promiscuous_mode = 0x1;		/* 1=on, 0=off */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	if (nic->flags & multicast_all)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		config->multicast_all = 0x1;		/* 1=accept, 0=no */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	/* disable WoL when up */
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 1928
diff changeset
  1205
	if (nic->ecdev ||
1812
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
			(netif_running(nic->netdev) || !(nic->flags & wol_magic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		config->magic_packet_disable = 0x1;	/* 1=off, 0=on */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	if (nic->mac >= mac_82558_D101_A4) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		config->fc_disable = 0x1;	/* 1=Tx fc off, 0=Tx fc on */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		config->mwi_enable = 0x1;	/* 1=enable, 0=disable */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		config->standard_tcb = 0x0;	/* 1=standard, 0=extended */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		config->rx_long_ok = 0x1;	/* 1=VLANs ok, 0=standard */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		if (nic->mac >= mac_82559_D101M) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
			config->tno_intr = 0x1;		/* TCO stats enable */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
			/* Enable TCO in extended config */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
			if (nic->mac >= mac_82551_10) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
				config->byte_count = 0x20; /* extended bytes */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
				config->rx_d102_mode = 0x1; /* GMRC for TCO */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
			}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
			config->standard_stat_counter = 0x0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	DPRINTK(HW, DEBUG, "[08-15]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		c[8], c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
	DPRINTK(HW, DEBUG, "[16-23]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
/*************************************************************************
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
*  CPUSaver parameters
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
*
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
*  All CPUSaver parameters are 16-bit literals that are part of a
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
*  "move immediate value" instruction.  By changing the value of
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
*  the literal in the instruction before the code is loaded, the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
*  driver can change the algorithm.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
*
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
*  INTDELAY - This loads the dead-man timer with its initial value.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
*    When this timer expires the interrupt is asserted, and the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
*    timer is reset each time a new packet is received.  (see
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
*    BUNDLEMAX below to set the limit on number of chained packets)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
*    The current default is 0x600 or 1536.  Experiments show that
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
*    the value should probably stay within the 0x200 - 0x1000.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
*
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
*  BUNDLEMAX -
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
*    This sets the maximum number of frames that will be bundled.  In
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
*    some situations, such as the TCP windowing algorithm, it may be
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
*    better to limit the growth of the bundle size than let it go as
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
*    high as it can, because that could cause too much added latency.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
*    The default is six, because this is the number of packets in the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
*    default TCP window size.  A value of 1 would make CPUSaver indicate
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
*    an interrupt for every frame received.  If you do not want to put
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
*    a limit on the bundle size, set this value to xFFFF.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
*
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
*  BUNDLESMALL -
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
*    This contains a bit-mask describing the minimum size frame that
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
*    will be bundled.  The default masks the lower 7 bits, which means
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
*    that any frame less than 128 bytes in length will not be bundled,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
*    but will instead immediately generate an interrupt.  This does
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
*    not affect the current bundle in any way.  Any frame that is 128
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
*    bytes or large will be bundled normally.  This feature is meant
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
*    to provide immediate indication of ACK frames in a TCP environment.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
*    Customers were seeing poor performance when a machine with CPUSaver
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
*    enabled was sending but not receiving.  The delay introduced when
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
*    the ACKs were received was enough to reduce total throughput, because
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
*    the sender would sit idle until the ACK was finally seen.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
*
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
*    The current default is 0xFF80, which masks out the lower 7 bits.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
*    This means that any frame which is x7F (127) bytes or smaller
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
*    will cause an immediate interrupt.  Because this value must be a
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
*    bit mask, there are only a few valid values that can be used.  To
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
*    turn this feature off, the driver can write the value xFFFF to the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
*    lower word of this instruction (in the same way that the other
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
*    parameters are used).  Likewise, a value of 0xF800 (2047) would
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
*    cause an interrupt to be generated for every frame, because all
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
*    standard Ethernet frames are <= 2047 bytes in length.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
*************************************************************************/
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
/* if you wish to disable the ucode functionality, while maintaining the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
 * workarounds it provides, set the following defines to:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
 * BUNDLESMALL 0
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
 * BUNDLEMAX 1
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
 * INTDELAY 1
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
#define BUNDLESMALL 1
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
#define BUNDLEMAX (u16)6
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
#define INTDELAY (u16)1536 /* 0x600 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
/* Initialize firmware */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
static const struct firmware *e100_request_firmware(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	const char *fw_name;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	const struct firmware *fw;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	u8 timer, bundle, min_size;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	int err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	/* do not load u-code for ICH devices */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	if (nic->flags & ich)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
		return NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	/* Search for ucode match against h/w revision */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	if (nic->mac == mac_82559_D101M)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
		fw_name = FIRMWARE_D101M;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
	else if (nic->mac == mac_82559_D101S)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
		fw_name = FIRMWARE_D101S;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	else if (nic->mac == mac_82551_F || nic->mac == mac_82551_10)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
		fw_name = FIRMWARE_D102E;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	else /* No ucode on other devices */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
		return NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
	err = request_firmware(&fw, fw_name, &nic->pdev->dev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
	if (err) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
		DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
			fw_name, err);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
		return ERR_PTR(err);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	/* Firmware should be precisely UCODE_SIZE (words) plus three bytes
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	   indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	if (fw->size != UCODE_SIZE * 4 + 3) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
		DPRINTK(PROBE, ERR, "Firmware \"%s\" has wrong size %zu\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
			fw_name, fw->size);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		release_firmware(fw);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
		return ERR_PTR(-EINVAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	/* Read timer, bundle and min_size from end of firmware blob */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	timer = fw->data[UCODE_SIZE * 4];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	bundle = fw->data[UCODE_SIZE * 4 + 1];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
	min_size = fw->data[UCODE_SIZE * 4 + 2];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	if (timer >= UCODE_SIZE || bundle >= UCODE_SIZE ||
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	    min_size >= UCODE_SIZE) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
		DPRINTK(PROBE, ERR,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
			"\"%s\" has bogus offset values (0x%x,0x%x,0x%x)\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
			fw_name, timer, bundle, min_size);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
		release_firmware(fw);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
		return ERR_PTR(-EINVAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	/* OK, firmware is validated and ready to use... */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	return fw;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
static void e100_setup_ucode(struct nic *nic, struct cb *cb,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
			     struct sk_buff *skb)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	const struct firmware *fw = (void *)skb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
	u8 timer, bundle, min_size;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	/* It's not a real skb; we just abused the fact that e100_exec_cb
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	   will pass it through to here... */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	cb->skb = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	/* firmware is stored as little endian already */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	memcpy(cb->u.ucode, fw->data, UCODE_SIZE * 4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	/* Read timer, bundle and min_size from end of firmware blob */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	timer = fw->data[UCODE_SIZE * 4];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	bundle = fw->data[UCODE_SIZE * 4 + 1];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	min_size = fw->data[UCODE_SIZE * 4 + 2];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
	/* Insert user-tunable settings in cb->u.ucode */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	cb->u.ucode[timer] &= cpu_to_le32(0xFFFF0000);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	cb->u.ucode[timer] |= cpu_to_le32(INTDELAY);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
	cb->u.ucode[bundle] &= cpu_to_le32(0xFFFF0000);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	cb->u.ucode[bundle] |= cpu_to_le32(BUNDLEMAX);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	cb->u.ucode[min_size] &= cpu_to_le32(0xFFFF0000);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
	cb->u.ucode[min_size] |= cpu_to_le32((BUNDLESMALL) ? 0xFFFF : 0xFF80);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	cb->command = cpu_to_le16(cb_ucode | cb_el);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
static inline int e100_load_ucode_wait(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	const struct firmware *fw;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	int err = 0, counter = 50;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	struct cb *cb = nic->cb_to_clean;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	fw = e100_request_firmware(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	/* If it's NULL, then no ucode is required */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	if (!fw || IS_ERR(fw))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
		return PTR_ERR(fw);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	if ((err = e100_exec_cb(nic, (void *)fw, e100_setup_ucode)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
		DPRINTK(PROBE,ERR, "ucode cmd failed with error %d\n", err);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	/* must restart cuc */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	nic->cuc_cmd = cuc_start;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
	/* wait for completion */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	e100_write_flush(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
	udelay(10);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	/* wait for possibly (ouch) 500ms */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	while (!(cb->status & cpu_to_le16(cb_complete))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
		msleep(10);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
		if (!--counter) break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
	/* ack any interrupts, something could have been set */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	iowrite8(~0, &nic->csr->scb.stat_ack);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	/* if the command failed, or is not OK, notify and return */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	if (!counter || !(cb->status & cpu_to_le16(cb_ok))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		DPRINTK(PROBE,ERR, "ucode load failed\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		err = -EPERM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	struct sk_buff *skb)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	cb->command = cpu_to_le16(cb_iaaddr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	memcpy(cb->u.iaaddr, nic->netdev->dev_addr, ETH_ALEN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	cb->command = cpu_to_le16(cb_dump);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	cb->u.dump_buffer_addr = cpu_to_le32(nic->dma_addr +
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		offsetof(struct mem, dump_buf));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
static int e100_phy_check_without_mii(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	u8 phy_type;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	int without_mii;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	switch (phy_type) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
	case NoSuchPhy: /* Non-MII PHY; UNTESTED! */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	case I82503: /* Non-MII PHY; UNTESTED! */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	case S80C24: /* Non-MII PHY; tested and working */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
		/* paragraph from the FreeBSD driver, "FXP_PHY_80C24":
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		 * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		 * doesn't have a programming interface of any sort.  The
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
		 * media is sensed automatically based on how the link partner
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
		 * is configured.  This is, in essence, manual configuration.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
		 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
		DPRINTK(PROBE, INFO,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
			 "found MII-less i82503 or 80c24 or other PHY\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
		nic->mdio_ctrl = mdio_ctrl_phy_mii_emulated;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
		nic->mii.phy_id = 0; /* is this ok for an MII-less PHY? */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		/* these might be needed for certain MII-less cards...
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
		 * nic->flags |= ich;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
		 * nic->flags |= ich_10h_workaround; */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
		without_mii = 1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
		break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	default:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
		without_mii = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
		break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	return without_mii;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
#define NCONFIG_AUTO_SWITCH	0x0080
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
#define MII_NSC_CONG		MII_RESV1
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
#define NSC_CONG_ENABLE		0x0100
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
#define NSC_CONG_TXREADY	0x0400
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
#define ADVERTISE_FC_SUPPORTED	0x0400
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
static int e100_phy_init(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
	struct net_device *netdev = nic->netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	u32 addr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	u16 bmcr, stat, id_lo, id_hi, cong;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
	/* Discover phy addr by searching addrs in order {1,0,2,..., 31} */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	for (addr = 0; addr < 32; addr++) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
		nic->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
		bmcr = mdio_read(netdev, nic->mii.phy_id, MII_BMCR);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
		stat = mdio_read(netdev, nic->mii.phy_id, MII_BMSR);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
		stat = mdio_read(netdev, nic->mii.phy_id, MII_BMSR);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
		if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
			break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	if (addr == 32) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
		/* uhoh, no PHY detected: check whether we seem to be some
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
		 * weird, rare variant which is *known* to not have any MII.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
		 * But do this AFTER MII checking only, since this does
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
		 * lookup of EEPROM values which may easily be unreliable. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
		if (e100_phy_check_without_mii(nic))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
			return 0; /* simply return and hope for the best */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
		else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
			/* for unknown cases log a fatal error */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
			DPRINTK(HW, ERR,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
				"Failed to locate any known PHY, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
			return -EAGAIN;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
	} else
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
		DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	/* Isolate all the PHY ids */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	for (addr = 0; addr < 32; addr++)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
		mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	/* Select the discovered PHY */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	bmcr &= ~BMCR_ISOLATE;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
	mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	/* Get phy ID */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
	id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	nic->phy = (u32)id_hi << 16 | (u32)id_lo;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
	DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	/* Handle National tx phys */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
#define NCS_PHY_MODEL_MASK	0xFFF0FFFF
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
		/* Disable congestion control */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		cong = mdio_read(netdev, nic->mii.phy_id, MII_NSC_CONG);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
		cong |= NSC_CONG_TXREADY;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
		cong &= ~NSC_CONG_ENABLE;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	if (nic->phy == phy_82552_v) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
		/* assign special tweaked mdio_ctrl() function */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
		nic->mdio_ctrl = mdio_ctrl_phy_82552_v;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
		/* Workaround Si not advertising flow-control during autoneg */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
		advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
		mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
		/* Reset for the above changes to take effect */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
		bmcr = mdio_read(netdev, nic->mii.phy_id, MII_BMCR);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
		bmcr |= BMCR_RESET;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
		mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	} else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	   (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) &&
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		!(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		/* enable/disable MDI/MDI-X auto-switching. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
				nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
static int e100_hw_init(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
	int err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	e100_hw_reset(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	DPRINTK(HW, ERR, "e100_hw_init\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	if (!in_interrupt() && (err = e100_self_test(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	if ((err = e100_phy_init(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
	if ((err = e100_exec_cmd(nic, cuc_load_base, 0)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	if ((err = e100_exec_cmd(nic, ruc_load_base, 0)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	if ((err = e100_load_ucode_wait(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	if ((err = e100_exec_cb(nic, NULL, e100_configure)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	if ((err = e100_exec_cb(nic, NULL, e100_setup_iaaddr)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	if ((err = e100_exec_cmd(nic, cuc_dump_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		nic->dma_addr + offsetof(struct mem, stats))))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	if ((err = e100_exec_cmd(nic, cuc_dump_reset, 0)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	e100_disable_irq(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	struct net_device *netdev = nic->netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
	struct dev_mc_list *list = netdev->mc_list;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	u16 i, count = min(netdev->mc_count, E100_MAX_MULTICAST_ADDRS);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	cb->command = cpu_to_le16(cb_multi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
	cb->u.multi.count = cpu_to_le16(count * ETH_ALEN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	for (i = 0; list && i < count; i++, list = list->next)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
		memcpy(&cb->u.multi.addr[i*ETH_ALEN], &list->dmi_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
			ETH_ALEN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
static void e100_set_multicast_list(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	DPRINTK(HW, DEBUG, "mc_count=%d, flags=0x%04X\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		netdev->mc_count, netdev->flags);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	if (netdev->flags & IFF_PROMISC)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		nic->flags |= promiscuous;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	else
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		nic->flags &= ~promiscuous;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	if (netdev->flags & IFF_ALLMULTI ||
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		netdev->mc_count > E100_MAX_MULTICAST_ADDRS)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		nic->flags |= multicast_all;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	else
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		nic->flags &= ~multicast_all;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	e100_exec_cb(nic, NULL, e100_configure);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	e100_exec_cb(nic, NULL, e100_multi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
static void e100_update_stats(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	struct net_device *dev = nic->netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	struct net_device_stats *ns = &dev->stats;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	struct stats *s = &nic->mem->stats;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
	__le32 *complete = (nic->mac < mac_82558_D101_A4) ? &s->fc_xmt_pause :
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		(nic->mac < mac_82559_D101M) ? (__le32 *)&s->xmt_tco_frames :
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		&s->complete;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
	/* Device's stats reporting may take several microseconds to
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	 * complete, so we're always waiting for results of the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
	 * previous command. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	if (*complete == cpu_to_le32(cuc_dump_reset_complete)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		*complete = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		nic->tx_frames = le32_to_cpu(s->tx_good_frames);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		nic->tx_collisions = le32_to_cpu(s->tx_total_collisions);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		ns->tx_aborted_errors += le32_to_cpu(s->tx_max_collisions);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		ns->tx_window_errors += le32_to_cpu(s->tx_late_collisions);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		ns->tx_carrier_errors += le32_to_cpu(s->tx_lost_crs);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		ns->tx_fifo_errors += le32_to_cpu(s->tx_underruns);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		ns->collisions += nic->tx_collisions;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		ns->tx_errors += le32_to_cpu(s->tx_max_collisions) +
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
			le32_to_cpu(s->tx_lost_crs);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors) +
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
			nic->rx_over_length_errors;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		ns->rx_crc_errors += le32_to_cpu(s->rx_crc_errors);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		ns->rx_frame_errors += le32_to_cpu(s->rx_alignment_errors);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		ns->rx_over_errors += le32_to_cpu(s->rx_overrun_errors);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
		ns->rx_fifo_errors += le32_to_cpu(s->rx_overrun_errors);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
		ns->rx_missed_errors += le32_to_cpu(s->rx_resource_errors);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
		ns->rx_errors += le32_to_cpu(s->rx_crc_errors) +
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
			le32_to_cpu(s->rx_alignment_errors) +
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
			le32_to_cpu(s->rx_short_frame_errors) +
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
			le32_to_cpu(s->rx_cdt_errors);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		nic->tx_deferred += le32_to_cpu(s->tx_deferred);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		nic->tx_single_collisions +=
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
			le32_to_cpu(s->tx_single_collisions);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
		nic->tx_multiple_collisions +=
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
			le32_to_cpu(s->tx_multiple_collisions);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
		if (nic->mac >= mac_82558_D101_A4) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
			nic->tx_fc_pause += le32_to_cpu(s->fc_xmt_pause);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
			nic->rx_fc_pause += le32_to_cpu(s->fc_rcv_pause);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
			nic->rx_fc_unsupported +=
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
				le32_to_cpu(s->fc_rcv_unsupported);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
			if (nic->mac >= mac_82559_D101M) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
				nic->tx_tco_frames +=
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
					le16_to_cpu(s->xmt_tco_frames);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
				nic->rx_tco_frames +=
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
					le16_to_cpu(s->rcv_tco_frames);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
			}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	if (e100_exec_cmd(nic, cuc_dump_reset, 0))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		DPRINTK(TX_ERR, DEBUG, "exec cuc_dump_reset failed\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	/* Adjust inter-frame-spacing (IFS) between two transmits if
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	 * we're getting collisions on a half-duplex connection. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	if (duplex == DUPLEX_HALF) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
		u32 prev = nic->adaptive_ifs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
		u32 min_frames = (speed == SPEED_100) ? 1000 : 100;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		if ((nic->tx_frames / 32 < nic->tx_collisions) &&
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
		   (nic->tx_frames > min_frames)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
			if (nic->adaptive_ifs < 60)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
				nic->adaptive_ifs += 5;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
		} else if (nic->tx_frames < min_frames) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
			if (nic->adaptive_ifs >= 5)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
				nic->adaptive_ifs -= 5;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		if (nic->adaptive_ifs != prev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
			e100_exec_cb(nic, NULL, e100_configure);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
static void e100_watchdog(unsigned long data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	struct nic *nic = (struct nic *)data;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	struct ethtool_cmd cmd;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	DPRINTK(TIMER, DEBUG, "right now = %ld\n", jiffies);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	/* mii library handles link maintenance tasks */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
    if (nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
    	ecdev_set_link(nic->ecdev, mii_link_ok(&nic->mii) ? 1 : 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
		mii_ethtool_gset(&nic->mii, &cmd);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
		if (mii_link_ok(&nic->mii) && !netif_carrier_ok(nic->netdev)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
			printk(KERN_INFO "e100: %s NIC Link is Up %s Mbps %s Duplex\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
					nic->netdev->name,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
					cmd.speed == SPEED_100 ? "100" : "10",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
					cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
		} else if (!mii_link_ok(&nic->mii) && netif_carrier_ok(nic->netdev)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
			printk(KERN_INFO "e100: %s NIC Link is Down\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
					nic->netdev->name);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		mii_check_link(&nic->mii);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		/* Software generated interrupt to recover from (rare) Rx
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		 * allocation failure.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		 * Unfortunately have to use a spinlock to not re-enable interrupts
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
		 * accidentally, due to hardware that shares a register between the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		 * interrupt mask bit and the SW Interrupt generation bit */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		spin_lock_irq(&nic->cmd_lock);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
		iowrite8(ioread8(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		e100_write_flush(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		spin_unlock_irq(&nic->cmd_lock);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		e100_update_stats(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		e100_adjust_adaptive_ifs(nic, cmd.speed, cmd.duplex);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		if (nic->mac <= mac_82557_D100_C)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
			/* Issue a multicast command to workaround a 557 lock up */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
			e100_set_multicast_list(nic->netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		if (nic->flags & ich && cmd.speed==SPEED_10 && cmd.duplex==DUPLEX_HALF)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
			/* Need SW workaround for ICH[x] 10Mbps/half duplex Tx hang. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
			nic->flags |= ich_10h_workaround;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		else
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
			nic->flags &= ~ich_10h_workaround;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
		mod_timer(&nic->watchdog,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
				round_jiffies(jiffies + E100_WATCHDOG_PERIOD));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
static void e100_xmit_prepare(struct nic *nic, struct cb *cb,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	struct sk_buff *skb)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	cb->command = nic->tx_command;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	/* interrupt every 16 packets regardless of delay */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
	if ((nic->cbs_avail & ~15) == nic->cbs_avail)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
		cb->command |= cpu_to_le16(cb_i);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	cb->u.tcb.tcb_byte_count = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	cb->u.tcb.threshold = nic->tx_threshold;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	cb->u.tcb.tbd_count = 1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		skb->data, skb->len, PCI_DMA_TODEVICE));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	/* check for mapping failure? */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	cb->u.tcb.tbd.size = cpu_to_le16(skb->len);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	int err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	if (nic->flags & ich_10h_workaround) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		/* SW workaround for ICH[x] 10Mbps/half duplex Tx hang.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		   Issue a NOP command followed by a 1us delay before
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		   issuing the Tx command. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		if (e100_exec_cmd(nic, cuc_nop, 0))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
			DPRINTK(TX_ERR, DEBUG, "exec cuc_nop failed\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		udelay(1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	err = e100_exec_cb(nic, skb, e100_xmit_prepare);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	switch (err) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	case -ENOSPC:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		/* We queued the skb, but now we're out of space. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		DPRINTK(TX_ERR, DEBUG, "No space for CB\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
		if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
			netif_stop_queue(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
	case -ENOMEM:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		/* This is a hard error - log it. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		DPRINTK(TX_ERR, DEBUG, "Out of Tx resources, returning skb\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
			netif_stop_queue(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
		return NETDEV_TX_BUSY;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	netdev->trans_start = jiffies;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
static int e100_tx_clean(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	struct net_device *dev = nic->netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	struct cb *cb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	int tx_cleaned = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
		spin_lock(&nic->cb_lock);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	/* Clean CBs marked complete */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	for (cb = nic->cb_to_clean;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
	    cb->status & cpu_to_le16(cb_complete);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	    cb = nic->cb_to_clean = cb->next) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		DPRINTK(TX_DONE, DEBUG, "cb[%d]->status = 0x%04X\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		        (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		        cb->status);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
		if (likely(cb->skb != NULL)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
			dev->stats.tx_packets++;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
			dev->stats.tx_bytes += cb->skb->len;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
			pci_unmap_single(nic->pdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
				le32_to_cpu(cb->u.tcb.tbd.buf_addr),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
				le16_to_cpu(cb->u.tcb.tbd.size),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
				PCI_DMA_TODEVICE);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
			if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
				dev_kfree_skb_any(cb->skb);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
			cb->skb = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
			tx_cleaned = 1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		cb->status = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		nic->cbs_avail++;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	if (!nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
		spin_unlock(&nic->cb_lock);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
		/* Recover from running out of Tx resources in xmit_frame */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		if (unlikely(tx_cleaned && netif_queue_stopped(nic->netdev)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
			netif_wake_queue(nic->netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
	return tx_cleaned;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
static void e100_clean_cbs(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
	if (nic->cbs) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
		while (nic->cbs_avail != nic->params.cbs.count) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
			struct cb *cb = nic->cb_to_clean;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
			if (cb->skb) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
				pci_unmap_single(nic->pdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
					le32_to_cpu(cb->u.tcb.tbd.buf_addr),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
					le16_to_cpu(cb->u.tcb.tbd.size),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
					PCI_DMA_TODEVICE);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
				if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
					dev_kfree_skb(cb->skb);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
			}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
			nic->cb_to_clean = nic->cb_to_clean->next;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
			nic->cbs_avail++;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		pci_free_consistent(nic->pdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
			sizeof(struct cb) * nic->params.cbs.count,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
			nic->cbs, nic->cbs_dma_addr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
		nic->cbs = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
		nic->cbs_avail = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	nic->cuc_cmd = cuc_start;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean =
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
		nic->cbs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
static int e100_alloc_cbs(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	struct cb *cb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
	unsigned int i, count = nic->params.cbs.count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	nic->cuc_cmd = cuc_start;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
	nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	nic->cbs_avail = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	nic->cbs = pci_alloc_consistent(nic->pdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		sizeof(struct cb) * count, &nic->cbs_dma_addr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
	if (!nic->cbs)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		return -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	for (cb = nic->cbs, i = 0; i < count; cb++, i++) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		cb->next = (i + 1 < count) ? cb + 1 : nic->cbs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		cb->prev = (i == 0) ? nic->cbs + count - 1 : cb - 1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
		cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
		cb->link = cpu_to_le32(nic->cbs_dma_addr +
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
			((i+1) % count) * sizeof(struct cb));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
		cb->skb = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
	nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	nic->cbs_avail = count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
static inline void e100_start_receiver(struct nic *nic, struct rx *rx)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	if (!nic->rxs) return;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
	if (RU_SUSPENDED != nic->ru_running) return;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
	/* handle init time starts */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	if (!rx) rx = nic->rxs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	/* (Re)start RU if suspended or idle and RFA is non-NULL */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
	if (rx->skb) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
		e100_exec_cmd(nic, ruc_start, rx->dma_addr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
		nic->ru_running = RU_RUNNING;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
#define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	if (!(rx->skb = netdev_alloc_skb(nic->netdev, RFD_BUF_LEN + NET_IP_ALIGN)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
		return -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	/* Align, init, and map the RFD. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	skb_reserve(rx->skb, NET_IP_ALIGN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
	skb_copy_to_linear_data(rx->skb, &nic->blank_rfd, sizeof(struct rfd));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
		RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	if (pci_dma_mapping_error(nic->pdev, rx->dma_addr)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
		dev_kfree_skb_any(rx->skb);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
		rx->skb = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
		rx->dma_addr = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
		return -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	/* Link the RFD to end of RFA by linking previous RFD to
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	 * this one.  We are safe to touch the previous RFD because
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	 * it is protected by the before last buffer's el bit being set */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
	if (rx->prev->skb) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
		struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
		put_unaligned_le32(rx->dma_addr, &prev_rfd->link);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
		pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
			sizeof(struct rfd), PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
static int e100_rx_indicate(struct nic *nic, struct rx *rx,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	unsigned int *work_done, unsigned int work_to_do)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	struct net_device *dev = nic->netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	struct sk_buff *skb = rx->skb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	struct rfd *rfd = (struct rfd *)skb->data;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	u16 rfd_status, actual_size;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
	if (unlikely(work_done && *work_done >= work_to_do))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
		return -EAGAIN;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	/* Need to sync before taking a peek at cb_complete bit */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	pci_dma_sync_single_for_cpu(nic->pdev, rx->dma_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		sizeof(struct rfd), PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	rfd_status = le16_to_cpu(rfd->status);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
	DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
	/* If data isn't ready, nothing to indicate */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
	if (unlikely(!(rfd_status & cb_complete))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
		/* If the next buffer has the el bit, but we think the receiver
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
		 * is still running, check to see if it really stopped while
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
		 * we had interrupts off.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
		 * This allows for a fast restart without re-enabling
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		 * interrupts */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		if ((le16_to_cpu(rfd->command) & cb_el) &&
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
		    (RU_RUNNING == nic->ru_running))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
			if (ioread8(&nic->csr->scb.status) & rus_no_res)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
				nic->ru_running = RU_SUSPENDED;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
		pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
					       sizeof(struct rfd),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
					       PCI_DMA_FROMDEVICE);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
		return -ENODATA;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	/* Get actual data size */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	if (unlikely(actual_size > RFD_BUF_LEN - sizeof(struct rfd)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
		actual_size = RFD_BUF_LEN - sizeof(struct rfd);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	/* Get data */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	pci_unmap_single(nic->pdev, rx->dma_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
		RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	/* If this buffer has the el bit, but we think the receiver
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	 * is still running, check to see if it really stopped while
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	 * we had interrupts off.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
	 * This allows for a fast restart without re-enabling interrupts.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	 * This can happen when the RU sees the size change but also sees
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	 * the el bit set. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	if ((le16_to_cpu(rfd->command) & cb_el) &&
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	    (RU_RUNNING == nic->ru_running)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	    if (ioread8(&nic->csr->scb.status) & rus_no_res)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
		nic->ru_running = RU_SUSPENDED;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
	if (!nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
		/* Pull off the RFD and put the actual data (minus eth hdr) */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		skb_reserve(skb, sizeof(struct rfd));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		skb_put(skb, actual_size);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		skb->protocol = eth_type_trans(skb, nic->netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	if (unlikely(!(rfd_status & cb_ok))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		if (!nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
			/* Don't indicate if hardware indicates errors */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
			dev_kfree_skb_any(skb);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
	} else if (actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
		/* Don't indicate oversized frames */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
		nic->rx_over_length_errors++;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
		if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
			dev_kfree_skb_any(skb);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
		dev->stats.rx_packets++;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
		dev->stats.rx_bytes += actual_size;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
		if (nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
			ecdev_receive(nic->ecdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
					skb->data + sizeof(struct rfd), actual_size);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
			// No need to detect link status as
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
			// long as frames are received: Reset watchdog.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
			nic->ec_watchdog_jiffies = jiffies;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
		} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
			netif_receive_skb(skb);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		if (work_done)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
			(*work_done)++;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
	if (nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
		// make receive frame descriptior usable again
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
		memcpy(skb->data, &nic->blank_rfd, sizeof(struct rfd));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
		rx->dma_addr = pci_map_single(nic->pdev, skb->data,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
				RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
		if (pci_dma_mapping_error(nic->pdev, rx->dma_addr)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
			rx->dma_addr = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
		/* Link the RFD to end of RFA by linking previous RFD to
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
		 * this one.  We are safe to touch the previous RFD because
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		 * it is protected by the before last buffer's el bit being set */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
		if (rx->prev->skb) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
			struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
			put_unaligned_le32(rx->dma_addr, &prev_rfd->link);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
					sizeof(struct rfd), PCI_DMA_TODEVICE);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
		rx->skb = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	unsigned int work_to_do)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
	struct rx *rx;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	int restart_required = 0, err = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	struct rx *old_before_last_rx, *new_before_last_rx;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	struct rfd *old_before_last_rfd, *new_before_last_rfd;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	/* Indicate newly arrived packets */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	for (rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
		err = e100_rx_indicate(nic, rx, work_done, work_to_do);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
		/* Hit quota or no more to clean */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
		if (-EAGAIN == err || -ENODATA == err)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
			break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
	/* On EAGAIN, hit quota so have more work to do, restart once
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	 * cleanup is complete.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
	 * Else, are we already rnr? then pay attention!!! this ensures that
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
	 * the state machine progression never allows a start with a
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
	 * partially cleaned list, avoiding a race between hardware
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	 * and rx_to_clean when in NAPI mode */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	if (-EAGAIN != err && RU_SUSPENDED == nic->ru_running)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
		restart_required = 1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	old_before_last_rx = nic->rx_to_use->prev->prev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	old_before_last_rfd = (struct rfd *)old_before_last_rx->skb->data;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	if (!nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
		/* Alloc new skbs to refill list */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
		for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
			if(unlikely(e100_rx_alloc_skb(nic, rx)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
				break; /* Better luck next time (see watchdog) */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	new_before_last_rx = nic->rx_to_use->prev->prev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
	if (new_before_last_rx != old_before_last_rx) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
		/* Set the el-bit on the buffer that is before the last buffer.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
		 * This lets us update the next pointer on the last buffer
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
		 * without worrying about hardware touching it.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
		 * We set the size to 0 to prevent hardware from touching this
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
		 * buffer.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		 * When the hardware hits the before last buffer with el-bit
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
		 * and size of 0, it will RNR interrupt, the RUS will go into
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
		 * the No Resources state.  It will not complete nor write to
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
		 * this buffer. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
		new_before_last_rfd =
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
			(struct rfd *)new_before_last_rx->skb->data;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
		new_before_last_rfd->size = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
		new_before_last_rfd->command |= cpu_to_le16(cb_el);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		pci_dma_sync_single_for_device(nic->pdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
			new_before_last_rx->dma_addr, sizeof(struct rfd),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
			PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
		/* Now that we have a new stopping point, we can clear the old
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
		 * stopping point.  We must sync twice to get the proper
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
		 * ordering on the hardware side of things. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
		old_before_last_rfd->command &= ~cpu_to_le16(cb_el);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
		pci_dma_sync_single_for_device(nic->pdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
			old_before_last_rx->dma_addr, sizeof(struct rfd),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
			PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
		old_before_last_rfd->size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
		pci_dma_sync_single_for_device(nic->pdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
			old_before_last_rx->dma_addr, sizeof(struct rfd),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
			PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	if (restart_required) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
		// ack the rnr?
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
		iowrite8(stat_ack_rnr, &nic->csr->scb.stat_ack);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
		e100_start_receiver(nic, nic->rx_to_clean);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
		if (work_done)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
			(*work_done)++;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
static void e100_rx_clean_list(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
	struct rx *rx;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	unsigned int i, count = nic->params.rfds.count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	nic->ru_running = RU_UNINITIALIZED;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	if (nic->rxs) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
		for (rx = nic->rxs, i = 0; i < count; rx++, i++) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
			if (rx->skb) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
				pci_unmap_single(nic->pdev, rx->dma_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
					RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
				dev_kfree_skb(rx->skb);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
			}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
		kfree(nic->rxs);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
		nic->rxs = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
	nic->rx_to_use = nic->rx_to_clean = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
static int e100_rx_alloc_list(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
	struct rx *rx;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
	unsigned int i, count = nic->params.rfds.count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	struct rfd *before_last;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
	nic->rx_to_use = nic->rx_to_clean = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	nic->ru_running = RU_UNINITIALIZED;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
	if (!(nic->rxs = kcalloc(count, sizeof(struct rx), GFP_ATOMIC)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
		return -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	for (rx = nic->rxs, i = 0; i < count; rx++, i++) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
		rx->next = (i + 1 < count) ? rx + 1 : nic->rxs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
		rx->prev = (i == 0) ? nic->rxs + count - 1 : rx - 1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
		if (e100_rx_alloc_skb(nic, rx)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
			e100_rx_clean_list(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
			return -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	if (!nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
		/* Set the el-bit on the buffer that is before the last buffer.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
		 * This lets us update the next pointer on the last buffer without
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
		 * worrying about hardware touching it.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
		 * We set the size to 0 to prevent hardware from touching this buffer.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
		 * When the hardware hits the before last buffer with el-bit and size
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
		 * of 0, it will RNR interrupt, the RU will go into the No Resources
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
		 * state.  It will not complete nor write to this buffer. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
		rx = nic->rxs->prev->prev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
		before_last = (struct rfd *)rx->skb->data;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
		before_last->command |= cpu_to_le16(cb_el);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
		before_last->size = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
		pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
				sizeof(struct rfd), PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
	nic->rx_to_use = nic->rx_to_clean = nic->rxs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	nic->ru_running = RU_SUSPENDED;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
static irqreturn_t e100_intr(int irq, void *dev_id)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
	struct net_device *netdev = dev_id;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	u8 stat_ack = ioread8(&nic->csr->scb.stat_ack);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
	DPRINTK(INTR, DEBUG, "stat_ack = 0x%02X\n", stat_ack);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	if (stat_ack == stat_ack_not_ours ||	/* Not our interrupt */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	   stat_ack == stat_ack_not_present)	/* Hardware is ejected */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
		return IRQ_NONE;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	/* Ack interrupt(s) */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	iowrite8(stat_ack, &nic->csr->scb.stat_ack);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	/* We hit Receive No Resource (RNR); restart RU after cleaning */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
	if (stat_ack & stat_ack_rnr)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
		nic->ru_running = RU_SUSPENDED;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	if (!nic->ecdev && likely(napi_schedule_prep(&nic->napi))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
		e100_disable_irq(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
		__napi_schedule(&nic->napi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	return IRQ_HANDLED;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
void e100_ec_poll(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	e100_rx_clean(nic, NULL, 100);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	e100_tx_clean(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
    if (jiffies - nic->ec_watchdog_jiffies >= 2 * HZ) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
        e100_watchdog((unsigned long) nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
        nic->ec_watchdog_jiffies = jiffies;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
    }
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
static int e100_poll(struct napi_struct *napi, int budget)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	struct nic *nic = container_of(napi, struct nic, napi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	unsigned int work_done = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	e100_rx_clean(nic, &work_done, budget);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	e100_tx_clean(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	/* If budget not fully consumed, exit the polling mode */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	if (work_done < budget) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
		napi_complete(napi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
		e100_enable_irq(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	return work_done;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
#ifdef CONFIG_NET_POLL_CONTROLLER
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
static void e100_netpoll(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	e100_disable_irq(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
	e100_intr(nic->pdev->irq, netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	e100_tx_clean(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
	e100_enable_irq(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
#endif
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
static int e100_set_mac_address(struct net_device *netdev, void *p)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
	struct sockaddr *addr = p;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	if (!is_valid_ether_addr(addr->sa_data))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
		return -EADDRNOTAVAIL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	e100_exec_cb(nic, NULL, e100_setup_iaaddr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
static int e100_change_mtu(struct net_device *netdev, int new_mtu)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	if (new_mtu < ETH_ZLEN || new_mtu > ETH_DATA_LEN)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
		return -EINVAL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
	netdev->mtu = new_mtu;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
static int e100_asf(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	/* ASF can be enabled from eeprom */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	return((nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) &&
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	   (nic->eeprom[eeprom_config_asf] & eeprom_asf) &&
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	   !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) &&
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	   ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
static int e100_up(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
	int err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	if ((err = e100_rx_alloc_list(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
	if ((err = e100_alloc_cbs(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
		goto err_rx_clean_list;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	if ((err = e100_hw_init(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
		goto err_clean_cbs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	e100_set_multicast_list(nic->netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	e100_start_receiver(nic, NULL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	if (!nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		mod_timer(&nic->watchdog, jiffies);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
	if ((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
		nic->netdev->name, nic->netdev)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		goto err_no_irq;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
	if (!nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		netif_wake_queue(nic->netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		napi_enable(&nic->napi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
		/* enable ints _after_ enabling poll, preventing a race between
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		 * disable ints+schedule */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		e100_enable_irq(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
err_no_irq:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		del_timer_sync(&nic->watchdog);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
err_clean_cbs:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	e100_clean_cbs(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
err_rx_clean_list:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	e100_rx_clean_list(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
	return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
static void e100_down(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
	if (!nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
		/* wait here for poll to complete */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		napi_disable(&nic->napi);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
		netif_stop_queue(nic->netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	e100_hw_reset(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	free_irq(nic->pdev->irq, nic->netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	if (!nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
		del_timer_sync(&nic->watchdog);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
		netif_carrier_off(nic->netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	e100_clean_cbs(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	e100_rx_clean_list(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
static void e100_tx_timeout(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	/* Reset outside of interrupt context, to avoid request_irq
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	 * in interrupt context */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
	schedule_work(&nic->tx_timeout_task);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
static void e100_tx_timeout_task(struct work_struct *work)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	struct nic *nic = container_of(work, struct nic, tx_timeout_task);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
	struct net_device *netdev = nic->netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
	DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
		ioread8(&nic->csr->scb.status));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
	e100_down(netdev_priv(netdev));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	e100_up(netdev_priv(netdev));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	int err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
	struct sk_buff *skb;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	/* Use driver resources to perform internal MAC or PHY
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	 * loopback test.  A single packet is prepared and transmitted
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	 * in loopback mode, and the test passes if the received
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
	 * packet compares byte-for-byte to the transmitted packet. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
	if ((err = e100_rx_alloc_list(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	if ((err = e100_alloc_cbs(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
		goto err_clean_rx;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	/* ICH PHY loopback is broken so do MAC loopback instead */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
	if (nic->flags & ich && loopback_mode == lb_phy)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
		loopback_mode = lb_mac;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
	nic->loopback = loopback_mode;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
	if ((err = e100_hw_init(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
		goto err_loopback_none;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
	if (loopback_mode == lb_phy)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
		mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
			BMCR_LOOPBACK);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	e100_start_receiver(nic, NULL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	if (!(skb = netdev_alloc_skb(nic->netdev, ETH_DATA_LEN))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		err = -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
		goto err_loopback_none;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	skb_put(skb, ETH_DATA_LEN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	memset(skb->data, 0xFF, ETH_DATA_LEN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
	e100_xmit_frame(skb, nic->netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	msleep(10);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	pci_dma_sync_single_for_cpu(nic->pdev, nic->rx_to_clean->dma_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
			RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	if (memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	   skb->data, ETH_DATA_LEN))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
		err = -EAGAIN;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
err_loopback_none:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	nic->loopback = lb_none;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
	e100_clean_cbs(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
	e100_hw_reset(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
err_clean_rx:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
	e100_rx_clean_list(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
#define MII_LED_CONTROL	0x1B
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
#define E100_82552_LED_OVERRIDE 0x19
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
#define E100_82552_LED_ON       0x000F /* LEDTX and LED_RX both on */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
#define E100_82552_LED_OFF      0x000A /* LEDTX and LED_RX both off */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
static void e100_blink_led(unsigned long data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	struct nic *nic = (struct nic *)data;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	enum led_state {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
		led_on     = 0x01,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
		led_off    = 0x04,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
		led_on_559 = 0x05,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		led_on_557 = 0x07,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
	u16 led_reg = MII_LED_CONTROL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
	if (nic->phy == phy_82552_v) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
		led_reg = E100_82552_LED_OVERRIDE;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
		nic->leds = (nic->leds == E100_82552_LED_ON) ?
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
		            E100_82552_LED_OFF : E100_82552_LED_ON;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
	} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
		nic->leds = (nic->leds & led_on) ? led_off :
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
		            (nic->mac < mac_82559_D101M) ? led_on_557 :
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
		            led_on_559;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
	mdio_write(nic->netdev, nic->mii.phy_id, led_reg, nic->leds);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
	mod_timer(&nic->blink_timer, jiffies + HZ / 4);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
static int e100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
	return mii_ethtool_gset(&nic->mii, cmd);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
static int e100_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
	int err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
	mdio_write(netdev, nic->mii.phy_id, MII_BMCR, BMCR_RESET);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	err = mii_ethtool_sset(&nic->mii, cmd);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
	e100_exec_cb(nic, NULL, e100_configure);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
static void e100_get_drvinfo(struct net_device *netdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	struct ethtool_drvinfo *info)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	strcpy(info->driver, DRV_NAME);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
	strcpy(info->version, DRV_VERSION);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	strcpy(info->fw_version, "N/A");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	strcpy(info->bus_info, pci_name(nic->pdev));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
#define E100_PHY_REGS 0x1C
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
static int e100_get_regs_len(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
	return 1 + E100_PHY_REGS + sizeof(nic->mem->dump_buf);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
static void e100_get_regs(struct net_device *netdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
	struct ethtool_regs *regs, void *p)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
	u32 *buff = p;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	int i;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	regs->version = (1 << 24) | nic->pdev->revision;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
	buff[0] = ioread8(&nic->csr->scb.cmd_hi) << 24 |
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
		ioread8(&nic->csr->scb.cmd_lo) << 16 |
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
		ioread16(&nic->csr->scb.status);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	for (i = E100_PHY_REGS; i >= 0; i--)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
		buff[1 + E100_PHY_REGS - i] =
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
			mdio_read(netdev, nic->mii.phy_id, i);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
	memset(nic->mem->dump_buf, 0, sizeof(nic->mem->dump_buf));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	e100_exec_cb(nic, NULL, e100_dump);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
	msleep(10);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
	memcpy(&buff[2 + E100_PHY_REGS], nic->mem->dump_buf,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		sizeof(nic->mem->dump_buf));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
static void e100_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
	wol->supported = (nic->mac >= mac_82558_D101_A4) ?  WAKE_MAGIC : 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	wol->wolopts = (nic->flags & wol_magic) ? WAKE_MAGIC : 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
static int e100_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	if ((wol->wolopts && wol->wolopts != WAKE_MAGIC) ||
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
	    !device_can_wakeup(&nic->pdev->dev))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
		return -EOPNOTSUPP;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	if (wol->wolopts)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
		nic->flags |= wol_magic;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	else
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
		nic->flags &= ~wol_magic;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
	device_set_wakeup_enable(&nic->pdev->dev, wol->wolopts);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
	e100_exec_cb(nic, NULL, e100_configure);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
static u32 e100_get_msglevel(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	return nic->msg_enable;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
static void e100_set_msglevel(struct net_device *netdev, u32 value)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
	nic->msg_enable = value;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
static int e100_nway_reset(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
	return mii_nway_restart(&nic->mii);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
static u32 e100_get_link(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	return mii_link_ok(&nic->mii);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
static int e100_get_eeprom_len(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
	return nic->eeprom_wc << 1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
#define E100_EEPROM_MAGIC	0x1234
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
static int e100_get_eeprom(struct net_device *netdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	struct ethtool_eeprom *eeprom, u8 *bytes)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
	eeprom->magic = E100_EEPROM_MAGIC;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
	memcpy(bytes, &((u8 *)nic->eeprom)[eeprom->offset], eeprom->len);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
static int e100_set_eeprom(struct net_device *netdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	struct ethtool_eeprom *eeprom, u8 *bytes)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	if (eeprom->magic != E100_EEPROM_MAGIC)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
		return -EINVAL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
	memcpy(&((u8 *)nic->eeprom)[eeprom->offset], bytes, eeprom->len);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	return e100_eeprom_save(nic, eeprom->offset >> 1,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
		(eeprom->len >> 1) + 1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
static void e100_get_ringparam(struct net_device *netdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	struct ethtool_ringparam *ring)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	struct param_range *rfds = &nic->params.rfds;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	struct param_range *cbs = &nic->params.cbs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	ring->rx_max_pending = rfds->max;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	ring->tx_max_pending = cbs->max;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	ring->rx_mini_max_pending = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	ring->rx_jumbo_max_pending = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	ring->rx_pending = rfds->count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	ring->tx_pending = cbs->count;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	ring->rx_mini_pending = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	ring->rx_jumbo_pending = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
static int e100_set_ringparam(struct net_device *netdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	struct ethtool_ringparam *ring)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	struct param_range *rfds = &nic->params.rfds;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	struct param_range *cbs = &nic->params.cbs;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
		return -EINVAL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	if (netif_running(netdev))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
		e100_down(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	rfds->count = max(ring->rx_pending, rfds->min);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	rfds->count = min(rfds->count, rfds->max);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	cbs->count = max(ring->tx_pending, cbs->min);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	cbs->count = min(cbs->count, cbs->max);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	DPRINTK(DRV, INFO, "Ring Param settings: rx: %d, tx %d\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	        rfds->count, cbs->count);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
	if (netif_running(netdev))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		e100_up(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
static const char e100_gstrings_test[][ETH_GSTRING_LEN] = {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	"Link test     (on/offline)",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	"Eeprom test   (on/offline)",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
	"Self test        (offline)",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	"Mac loopback     (offline)",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	"Phy loopback     (offline)",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
#define E100_TEST_LEN	ARRAY_SIZE(e100_gstrings_test)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
static void e100_diag_test(struct net_device *netdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	struct ethtool_test *test, u64 *data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	struct ethtool_cmd cmd;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	int i, err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	memset(data, 0, E100_TEST_LEN * sizeof(u64));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	data[0] = !mii_link_ok(&nic->mii);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
	data[1] = e100_eeprom_load(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	if (test->flags & ETH_TEST_FL_OFFLINE) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
		/* save speed, duplex & autoneg settings */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
		err = mii_ethtool_gset(&nic->mii, &cmd);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		if (netif_running(netdev))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
			e100_down(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
		data[2] = e100_self_test(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
		data[3] = e100_loopback_test(nic, lb_mac);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
		data[4] = e100_loopback_test(nic, lb_phy);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
		/* restore speed, duplex & autoneg settings */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
		err = mii_ethtool_sset(&nic->mii, &cmd);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
		if (netif_running(netdev))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
			e100_up(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	for (i = 0; i < E100_TEST_LEN; i++)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
		test->flags |= data[i] ? ETH_TEST_FL_FAILED : 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	msleep_interruptible(4 * 1000);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
static int e100_phys_id(struct net_device *netdev, u32 data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	u16 led_reg = (nic->phy == phy_82552_v) ? E100_82552_LED_OVERRIDE :
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	              MII_LED_CONTROL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
	if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
		data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	mod_timer(&nic->blink_timer, jiffies);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
	msleep_interruptible(data * 1000);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	del_timer_sync(&nic->blink_timer);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
	mdio_write(netdev, nic->mii.phy_id, led_reg, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
static const char e100_gstrings_stats[][ETH_GSTRING_LEN] = {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
	"rx_length_errors", "rx_over_errors", "rx_crc_errors",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
	"rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	"tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
	"tx_heartbeat_errors", "tx_window_errors",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
	/* device-specific stats */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	"tx_deferred", "tx_single_collisions", "tx_multi_collisions",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
	"tx_flow_control_pause", "rx_flow_control_pause",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	"rx_flow_control_unsupported", "tx_tco_packets", "rx_tco_packets",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
#define E100_NET_STATS_LEN	21
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
#define E100_STATS_LEN	ARRAY_SIZE(e100_gstrings_stats)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
static int e100_get_sset_count(struct net_device *netdev, int sset)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	switch (sset) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	case ETH_SS_TEST:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
		return E100_TEST_LEN;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	case ETH_SS_STATS:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
		return E100_STATS_LEN;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
	default:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
		return -EOPNOTSUPP;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
static void e100_get_ethtool_stats(struct net_device *netdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
	struct ethtool_stats *stats, u64 *data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	int i;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	for (i = 0; i < E100_NET_STATS_LEN; i++)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
		data[i] = ((unsigned long *)&netdev->stats)[i];
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	data[i++] = nic->tx_deferred;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	data[i++] = nic->tx_single_collisions;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	data[i++] = nic->tx_multiple_collisions;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	data[i++] = nic->tx_fc_pause;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	data[i++] = nic->rx_fc_pause;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
	data[i++] = nic->rx_fc_unsupported;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	data[i++] = nic->tx_tco_frames;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
	data[i++] = nic->rx_tco_frames;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
static void e100_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	switch (stringset) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
	case ETH_SS_TEST:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
		memcpy(data, *e100_gstrings_test, sizeof(e100_gstrings_test));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	case ETH_SS_STATS:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
		memcpy(data, *e100_gstrings_stats, sizeof(e100_gstrings_stats));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		break;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
static const struct ethtool_ops e100_ethtool_ops = {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	.get_settings		= e100_get_settings,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
	.set_settings		= e100_set_settings,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
	.get_drvinfo		= e100_get_drvinfo,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
	.get_regs_len		= e100_get_regs_len,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
	.get_regs		= e100_get_regs,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
	.get_wol		= e100_get_wol,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
	.set_wol		= e100_set_wol,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	.get_msglevel		= e100_get_msglevel,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	.set_msglevel		= e100_set_msglevel,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	.nway_reset		= e100_nway_reset,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
	.get_link		= e100_get_link,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	.get_eeprom_len		= e100_get_eeprom_len,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	.get_eeprom		= e100_get_eeprom,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
	.set_eeprom		= e100_set_eeprom,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	.get_ringparam		= e100_get_ringparam,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	.set_ringparam		= e100_set_ringparam,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
	.self_test		= e100_diag_test,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	.get_strings		= e100_get_strings,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	.phys_id		= e100_phys_id,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	.get_ethtool_stats	= e100_get_ethtool_stats,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
	.get_sset_count		= e100_get_sset_count,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
	return generic_mii_ioctl(&nic->mii, if_mii(ifr), cmd, NULL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
static int e100_alloc(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	nic->mem = pci_alloc_consistent(nic->pdev, sizeof(struct mem),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		&nic->dma_addr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	return nic->mem ? 0 : -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
static void e100_free(struct nic *nic)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
	if (nic->mem) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
		pci_free_consistent(nic->pdev, sizeof(struct mem),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
			nic->mem, nic->dma_addr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
		nic->mem = NULL;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
static int e100_open(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	int err = 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
		netif_carrier_off(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	if ((err = e100_up(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
		DPRINTK(IFUP, ERR, "Cannot open interface, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
static int e100_close(struct net_device *netdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
	e100_down(netdev_priv(netdev));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
static const struct net_device_ops e100_netdev_ops = {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
	.ndo_open		= e100_open,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	.ndo_stop		= e100_close,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	.ndo_start_xmit		= e100_xmit_frame,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
	.ndo_validate_addr	= eth_validate_addr,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	.ndo_set_multicast_list	= e100_set_multicast_list,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
	.ndo_set_mac_address	= e100_set_mac_address,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
	.ndo_change_mtu		= e100_change_mtu,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	.ndo_do_ioctl		= e100_do_ioctl,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
	.ndo_tx_timeout		= e100_tx_timeout,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
#ifdef CONFIG_NET_POLL_CONTROLLER
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	.ndo_poll_controller	= e100_netpoll,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
#endif
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
static int __devinit e100_probe(struct pci_dev *pdev,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
	const struct pci_device_id *ent)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
	struct net_device *netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	struct nic *nic;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
	int err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
	if (!(netdev = alloc_etherdev(sizeof(struct nic)))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
		if (((1 << debug) - 1) & NETIF_MSG_PROBE)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
			printk(KERN_ERR PFX "Etherdev alloc failed, abort.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
		return -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	netdev->netdev_ops = &e100_netdev_ops;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
	SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
	nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
	netif_napi_add(netdev, &nic->napi, e100_poll, E100_NAPI_WEIGHT);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
	nic->netdev = netdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
	nic->pdev = pdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
	nic->msg_enable = (1 << debug) - 1;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	nic->mdio_ctrl = mdio_ctrl_hw;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
	pci_set_drvdata(pdev, netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
	if ((err = pci_enable_device(pdev))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
		DPRINTK(PROBE, ERR, "Cannot enable PCI device, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
		goto err_out_free_dev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		DPRINTK(PROBE, ERR, "Cannot find proper PCI device "
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
			"base address, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
		err = -ENODEV;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
		goto err_out_disable_pdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	if ((err = pci_request_regions(pdev, DRV_NAME))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
		DPRINTK(PROBE, ERR, "Cannot obtain PCI resources, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		goto err_out_disable_pdev;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
	if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		goto err_out_free_res;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	SET_NETDEV_DEV(netdev, &pdev->dev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	if (use_io)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
		DPRINTK(PROBE, INFO, "using i/o access mode\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	nic->csr = pci_iomap(pdev, (use_io ? 1 : 0), sizeof(struct csr));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	if (!nic->csr) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
		DPRINTK(PROBE, ERR, "Cannot map device registers, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
		err = -ENOMEM;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
		goto err_out_free_res;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
	if (ent->driver_data)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
		nic->flags |= ich;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	else
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
		nic->flags &= ~ich;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	e100_get_defaults(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	/* locks must be initialized before calling hw_reset */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	spin_lock_init(&nic->cb_lock);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	spin_lock_init(&nic->cmd_lock);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	spin_lock_init(&nic->mdio_lock);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
	/* Reset the device before pci_set_master() in case device is in some
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	 * funky state and has an interrupt pending - hint: we don't have the
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
	 * interrupt handler registered yet. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
	e100_hw_reset(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
	pci_set_master(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
	init_timer(&nic->watchdog);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
	nic->watchdog.function = e100_watchdog;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
	nic->watchdog.data = (unsigned long)nic;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
	init_timer(&nic->blink_timer);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	nic->blink_timer.function = e100_blink_led;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
	nic->blink_timer.data = (unsigned long)nic;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
	INIT_WORK(&nic->tx_timeout_task, e100_tx_timeout_task);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	if ((err = e100_alloc(nic))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		goto err_out_iounmap;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	if ((err = e100_eeprom_load(nic)))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		goto err_out_free;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	e100_phy_init(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	if (!is_valid_ether_addr(netdev->perm_addr)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		if (!eeprom_bad_csum_allow) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
			DPRINTK(PROBE, ERR, "Invalid MAC address from "
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
			        "EEPROM, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
			err = -EAGAIN;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
			goto err_out_free;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
		} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
			DPRINTK(PROBE, ERR, "Invalid MAC address from EEPROM, "
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
			        "you MUST configure one.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	/* Wol magic packet can be enabled from eeprom */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
	if ((nic->mac >= mac_82558_D101_A4) &&
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
	   (nic->eeprom[eeprom_id] & eeprom_id_wol)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		nic->flags |= wol_magic;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		device_set_wakeup_enable(&pdev->dev, true);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
	/* ack any pending wake events, disable PME */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
	pci_pme_active(pdev, false);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
	// offer device to EtherCAT master module
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	nic->ecdev = ecdev_offer(netdev, e100_ec_poll, THIS_MODULE);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	if (nic->ecdev) {
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 1928
diff changeset
  2974
		err = ecdev_open(nic->ecdev);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 1928
diff changeset
  2975
		if (err) {
1812
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
			ecdev_withdraw(nic->ecdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
			goto err_out_free;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		strcpy(netdev->name, "eth%d");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		if((err = register_netdev(netdev))) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
			DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
			goto err_out_free;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
	DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		(unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
		pdev->irq, netdev->dev_addr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
err_out_free:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
	e100_free(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
err_out_iounmap:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	pci_iounmap(pdev, nic->csr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
err_out_free_res:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	pci_release_regions(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
err_out_disable_pdev:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
	pci_disable_device(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
err_out_free_dev:
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	pci_set_drvdata(pdev, NULL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
	free_netdev(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
	return err;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
static void __devexit e100_remove(struct pci_dev *pdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
	struct net_device *netdev = pci_get_drvdata(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	if (netdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
		struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
		if (nic->ecdev) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
			ecdev_close(nic->ecdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
			ecdev_withdraw(nic->ecdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
		} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
			unregister_netdev(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
		e100_free(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
		pci_iounmap(pdev, nic->csr);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
		free_netdev(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
		pci_release_regions(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
		pci_disable_device(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
		pci_set_drvdata(pdev, NULL);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
#define E100_82552_SMARTSPEED   0x14   /* SmartSpeed Ctrl register */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
#define E100_82552_REV_ANEG     0x0200 /* Reverse auto-negotiation */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
#define E100_82552_ANEG_NOW     0x0400 /* Auto-negotiate now */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
	struct net_device *netdev = pci_get_drvdata(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	if (netif_running(netdev))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
		e100_down(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
	netif_device_detach(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	pci_save_state(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	if ((nic->flags & wol_magic) | e100_asf(nic)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
		/* enable reverse auto-negotiation */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
		if (nic->phy == phy_82552_v) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
			u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
			                           E100_82552_SMARTSPEED);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
			mdio_write(netdev, nic->mii.phy_id,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
			           E100_82552_SMARTSPEED, smartspeed |
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
			           E100_82552_REV_ANEG | E100_82552_ANEG_NOW);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
		*enable_wake = true;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	} else {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
		*enable_wake = false;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	pci_disable_device(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
static int __e100_power_off(struct pci_dev *pdev, bool wake)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
	if (wake)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
		return pci_prepare_to_sleep(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
	pci_wake_from_d3(pdev, false);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	pci_set_power_state(pdev, PCI_D3hot);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
#ifdef CONFIG_PM
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
	bool wake;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
	__e100_shutdown(pdev, &wake);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
	return __e100_power_off(pdev, wake);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
static int e100_resume(struct pci_dev *pdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	struct net_device *netdev = pci_get_drvdata(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	pci_set_power_state(pdev, PCI_D0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
	pci_restore_state(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	/* ack any pending wake events, disable PME */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	pci_enable_wake(pdev, 0, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
	/* disable reverse auto-negotiation */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
	if (nic->phy == phy_82552_v) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		                           E100_82552_SMARTSPEED);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
		mdio_write(netdev, nic->mii.phy_id,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
		           E100_82552_SMARTSPEED,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		           smartspeed & ~(E100_82552_REV_ANEG));
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	netif_device_attach(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
	if (netif_running(netdev))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
		e100_up(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
	return 0;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
#endif /* CONFIG_PM */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
static void e100_shutdown(struct pci_dev *pdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	bool wake;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
	__e100_shutdown(pdev, &wake);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
	if (system_state == SYSTEM_POWER_OFF)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
		__e100_power_off(pdev, wake);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
/* ------------------ PCI Error Recovery infrastructure  -------------- */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
/**
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
 * e100_io_error_detected - called when PCI error is detected.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
 * @pdev: Pointer to PCI device
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
 * @state: The current pci connection state
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
	struct net_device *netdev = pci_get_drvdata(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	if (nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
		return -EBUSY;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
	netif_device_detach(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	if (state == pci_channel_io_perm_failure)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
		return PCI_ERS_RESULT_DISCONNECT;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	if (netif_running(netdev))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
		e100_down(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	pci_disable_device(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	/* Request a slot reset. */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	return PCI_ERS_RESULT_NEED_RESET;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
/**
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
 * e100_io_slot_reset - called after the pci bus has been reset.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
 * @pdev: Pointer to PCI device
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
 * Restart the card from scratch.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
static pci_ers_result_t e100_io_slot_reset(struct pci_dev *pdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	struct net_device *netdev = pci_get_drvdata(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	if (nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		return -EBUSY;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	if (pci_enable_device(pdev)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
		return PCI_ERS_RESULT_DISCONNECT;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
	pci_set_master(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
	/* Only one device per card can do a reset */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	if (0 != PCI_FUNC(pdev->devfn))
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
		return PCI_ERS_RESULT_RECOVERED;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
	e100_hw_reset(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	e100_phy_init(nic);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	return PCI_ERS_RESULT_RECOVERED;
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
/**
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
 * e100_io_resume - resume normal operations
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
 * @pdev: Pointer to PCI device
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
 *
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
 * Resume normal operations after an error recovery
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
 * sequence has been completed.
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
 */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
static void e100_io_resume(struct pci_dev *pdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	struct net_device *netdev = pci_get_drvdata(pdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	struct nic *nic = netdev_priv(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	/* ack any pending wake events, disable PME */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	pci_enable_wake(pdev, 0, 0);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
		netif_device_attach(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	if (nic->ecdev || netif_running(netdev)) {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
		e100_open(netdev);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
		if (!nic->ecdev)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
			mod_timer(&nic->watchdog, jiffies);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
static struct pci_error_handlers e100_err_handler = {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	.error_detected = e100_io_error_detected,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	.slot_reset = e100_io_slot_reset,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	.resume = e100_io_resume,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
static struct pci_driver e100_driver = {
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	.name =         DRV_NAME,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	.id_table =     e100_id_table,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	.probe =        e100_probe,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	.remove =       __devexit_p(e100_remove),
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
#ifdef CONFIG_PM
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	/* Power Management hooks */
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	.suspend =      e100_suspend,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	.resume =       e100_resume,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
#endif
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	.shutdown =     e100_shutdown,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	.err_handler = &e100_err_handler,
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
};
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
static int __init e100_init_module(void)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	printk(KERN_INFO DRV_NAME " " DRV_DESCRIPTION " " DRV_VERSION
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
			", master " EC_MASTER_VERSION "\n");
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 1928
diff changeset
  3220
1812
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
 	return pci_register_driver(&e100_driver);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
static void __exit e100_cleanup_module(void)
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
{
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	printk(KERN_INFO DRV_NAME " cleaning up module...\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	pci_unregister_driver(&e100_driver);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	printk(KERN_INFO DRV_NAME " module cleaned up.\n");
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
}
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
module_init(e100_init_module);
b7ce5f9f13df Added e100 driver for 2.6.31.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
module_exit(e100_cleanup_module);