devices/8139too-3.10-ethercat.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2585 26480934a057
permissions -rw-r--r--
devices/ccat: revert "limit rx processing to one frame per poll"

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2585
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/******************************************************************************
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
 *  $Id$
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
 *  Copyright (C) 2006-2014  Florian Pose, Ingenieurgemeinschaft IgH
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
 *  This file is part of the IgH EtherCAT Master.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
 *  modify it under the terms of the GNU General Public License version 2, as
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
 *  published by the Free Software Foundation.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
 *  Public License for more details.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
 *  You should have received a copy of the GNU General Public License along
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
 *  with the IgH EtherCAT Master; if not, write to the Free Software
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
 *  ---
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
 *  The license mentioned above concerns the source code only. Using the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
 *  EtherCAT technology and brand is only permitted in compliance with the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
 *  industrial property and similar rights of Beckhoff Automation GmbH.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
 *  vim: noexpandtab
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
 *****************************************************************************/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
   \file
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
   EtherCAT driver for RTL8139-compatible NICs.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
*/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
/*****************************************************************************/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
/*
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
  Former documentation:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
	8139too.c: A RealTek RTL-8139 Fast Ethernet driver for Linux.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
	Maintained by Jeff Garzik <jgarzik@pobox.com>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
	Copyright 2000-2002 Jeff Garzik
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	Much code comes from Donald Becker's rtl8139.c driver,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	versions 1.13 and older.  This driver was originally based
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	on rtl8139.c version 1.07.  Header of rtl8139.c version 1.13:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	-----<snip>-----
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
        	Written 1997-2001 by Donald Becker.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
		This software may be used and distributed according to the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
		terms of the GNU General Public License (GPL), incorporated
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
		herein by reference.  Drivers based on or derived from this
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
		code fall under the GPL and must retain the authorship,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
		copyright and license notice.  This file is not a complete
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
		program and may only be used when the entire operating
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
		system is licensed under the GPL.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
		This driver is for boards based on the RTL8129 and RTL8139
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
		PCI ethernet chips.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
		The author may be reached as becker@scyld.com, or C/O Scyld
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
		Computing Corporation 410 Severn Ave., Suite 210 Annapolis
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
		MD 21403
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
		Support and updates available at
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
		http://www.scyld.com/network/rtl8139.html
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
		Twister-tuning table provided by Kinston
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
		<shangh@realtek.com.tw>.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	-----<snip>-----
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	This software may be used and distributed according to the terms
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	of the GNU General Public License, incorporated herein by reference.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	Contributors:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
		Donald Becker - he wrote the original driver, kudos to him!
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
		(but please don't e-mail him for support, this isn't his driver)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
		Tigran Aivazian - bug fixes, skbuff free cleanup
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
		Martin Mares - suggestions for PCI cleanup
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
		David S. Miller - PCI DMA and softnet updates
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
		Ernst Gill - fixes ported from BSD driver
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
		Daniel Kobras - identified specific locations of
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
			posted MMIO write bugginess
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
		Gerard Sharp - bug fix, testing and feedback
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
		David Ford - Rx ring wrap fix
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
		Dan DeMaggio - swapped RTL8139 cards with me, and allowed me
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
		to find and fix a crucial bug on older chipsets.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
		Donald Becker/Chris Butterworth/Marcus Westergren -
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
		Noticed various Rx packet size-related buglets.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
		Santiago Garcia Mantinan - testing and feedback
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
		Jens David - 2.2.x kernel backports
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
		Martin Dennett - incredibly helpful insight on undocumented
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
		features of the 8139 chips
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
		Jean-Jacques Michel - bug fix
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
		Tobias Ringström - Rx interrupt status checking suggestion
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
		Andrew Morton - Clear blocked signals, avoid
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
		buffer overrun setting current->comm.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
		Kalle Olavi Niemitalo - Wake-on-LAN ioctls
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
		Robert Kuebel - Save kernel thread from dying on any signal.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	Submitting bug reports:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
		"rtl8139-diag -mmmaaavvveefN" output
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
		enable RTL8139_DEBUG below, and look at 'dmesg' or kernel log
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
*/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
#define DRV_NAME	"ec_8139too"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
#define DRV_VERSION	"0.9.28"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
#include <linux/module.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
#include <linux/kernel.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
#include <linux/compiler.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
#include <linux/pci.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
#include <linux/init.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
#include <linux/interrupt.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
#include <linux/netdevice.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
#include <linux/etherdevice.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
#include <linux/rtnetlink.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
#include <linux/delay.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
#include <linux/ethtool.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
#include <linux/mii.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
#include <linux/completion.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
#include <linux/crc32.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
#include <linux/io.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
#include <linux/uaccess.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
#include <linux/gfp.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
#include <asm/irq.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
#include "../globals.h"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
#include "ecdev.h"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
#define RTL8139_DRIVER_NAME DRV_NAME \
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
	" EtherCAT-capable Fast Ethernet driver " \
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
	DRV_VERSION ", master " EC_MASTER_VERSION
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
#define PFX DRV_NAME ": "
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
/* Default Message level */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
#define RTL8139_DEF_MSG_ENABLE   (NETIF_MSG_DRV   | \
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
                                 NETIF_MSG_PROBE  | \
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
                                 NETIF_MSG_LINK)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
/* define to 1, 2 or 3 to enable copious debugging info */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
#define RTL8139_DEBUG 0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
/* define to 1 to disable lightweight runtime debugging checks */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
#undef RTL8139_NDEBUG
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
#ifdef RTL8139_NDEBUG
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
#  define assert(expr) do {} while (0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
#else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
#  define assert(expr) \
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
        if (unlikely(!(expr))) {				\
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
		pr_err("Assertion failed! %s,%s,%s,line=%d\n",	\
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
		       #expr, __FILE__, __func__, __LINE__);	\
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
        }
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
/* A few user-configurable values. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
/* media options */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
#define MAX_UNITS 8
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
/* Whether to use MMIO or PIO. Default to MMIO. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
#ifdef CONFIG_8139TOO_PIO
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
static bool use_io = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
#else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
static bool use_io = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
   The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
static int multicast_filter_limit = 32;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
/* bitmapped message enable number */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
static int debug = -1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
/*
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
 * Receive ring size
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
 * Warning: 64K ring has hardware issues and may lock up.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
#if defined(CONFIG_SH_DREAMCAST)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
#define RX_BUF_IDX 0	/* 8K ring */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
#else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
#define RX_BUF_IDX	2	/* 32K ring */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
#define RX_BUF_LEN	(8192 << RX_BUF_IDX)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
#define RX_BUF_PAD	16
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
#define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
#if RX_BUF_LEN == 65536
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
#define RX_BUF_TOT_LEN	RX_BUF_LEN
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
#else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
#define RX_BUF_TOT_LEN	(RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
/* Number of Tx descriptor registers. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
#define NUM_TX_DESC	4
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
/* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
#define MAX_ETH_FRAME_SIZE	1536
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
#define TX_BUF_SIZE	MAX_ETH_FRAME_SIZE
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
#define TX_BUF_TOT_LEN	(TX_BUF_SIZE * NUM_TX_DESC)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
/* PCI Tuning Parameters
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
   Threshold is bytes transferred to chip before transmission starts. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
#define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
/* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024, 7==end of packet. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
#define RX_FIFO_THRESH	7	/* Rx buffer level before first PCI xfer.  */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
#define RX_DMA_BURST	7	/* Maximum PCI burst, '6' is 1024 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
#define TX_RETRY	8	/* 0-15.  retries = 16 + (TX_RETRY * 16) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
/* Operational parameters that usually are not changed. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
/* Time in jiffies before concluding the transmitter is hung. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
#define TX_TIMEOUT  (6*HZ)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
enum {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	HAS_MII_XCVR = 0x010000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	HAS_CHIP_XCVR = 0x020000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	HAS_LNK_CHNG = 0x040000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
#define RTL_NUM_STATS 4		/* number of ETHTOOL_GSTATS u64's */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
#define RTL_REGS_VER 1		/* version of reg. data in ETHTOOL_GREGS */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
#define RTL_MIN_IO_SIZE 0x80
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
#define RTL8139B_IO_SIZE 256
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
#define RTL8129_CAPS	HAS_MII_XCVR
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
#define RTL8139_CAPS	(HAS_CHIP_XCVR|HAS_LNK_CHNG)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
typedef enum {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	RTL8139 = 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	RTL8129,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
} board_t;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
/* indexed by board_t, above */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
static const struct {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	const char *name;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	u32 hw_flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
} board_info[] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	{ "RealTek RTL8139", RTL8139_CAPS },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	{ "RealTek RTL8129", RTL8129_CAPS },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
static DEFINE_PCI_DEVICE_TABLE(rtl8139_pci_tbl) = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	{0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	{0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	{0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	{0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	{0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	{0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	{0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	{0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	{0x1259, 0xa11e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	{0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	{0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	{0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	{0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	{0x02ac, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	{0x018a, 0x0106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	{0x126c, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	{0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	{0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
#ifdef CONFIG_SH_SECUREEDGE5410
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	/* Bogus 8139 silicon reports 8129 without external PROM :-( */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
#ifdef CONFIG_8139TOO_8129
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	/* some crazy cards report invalid vendor ids like
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	 * 0x0001 here.  The other ids are valid and constant,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	 * so we simply don't match on the main vendor id.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	{PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	{PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	{PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, RTL8139 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	{0,}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
/* prevent driver from being loaded automatically */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
//MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
static struct {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	const char str[ETH_GSTRING_LEN];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
} ethtool_stats_keys[] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	{ "early_rx" },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	{ "tx_buf_mapped" },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	{ "tx_timeouts" },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	{ "rx_lost_in_ring" },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
/* The rest of these values should never change. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
/* Symbolic offsets to registers. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
enum RTL8139_registers {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	MAC0		= 0,	 /* Ethernet hardware address. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	MAR0		= 8,	 /* Multicast filter. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	TxStatus0	= 0x10,	 /* Transmit status (Four 32bit registers). */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	TxAddr0		= 0x20,	 /* Tx descriptors (also four 32bit). */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	RxBuf		= 0x30,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	ChipCmd		= 0x37,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
	RxBufPtr	= 0x38,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	RxBufAddr	= 0x3A,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
	IntrMask	= 0x3C,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	IntrStatus	= 0x3E,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	TxConfig	= 0x40,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	RxConfig	= 0x44,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	Timer		= 0x48,	 /* A general-purpose counter. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
	RxMissed	= 0x4C,  /* 24 bits valid, write clears. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	Cfg9346		= 0x50,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
	Config0		= 0x51,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	Config1		= 0x52,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
	TimerInt	= 0x54,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	MediaStatus	= 0x58,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
	Config3		= 0x59,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
	Config4		= 0x5A,	 /* absent on RTL-8139A */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	HltClk		= 0x5B,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
	MultiIntr	= 0x5C,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	TxSummary	= 0x60,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
	BasicModeCtrl	= 0x62,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	BasicModeStatus	= 0x64,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	NWayAdvert	= 0x66,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	NWayLPAR	= 0x68,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	NWayExpansion	= 0x6A,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	/* Undocumented registers, but required for proper operation. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	FIFOTMS		= 0x70,	 /* FIFO Control and test. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	CSCR		= 0x74,	 /* Chip Status and Configuration Register. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	PARA78		= 0x78,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	FlashReg	= 0xD4,	/* Communication with Flash ROM, four bytes. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	PARA7c		= 0x7c,	 /* Magic transceiver parameter register. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	Config5		= 0xD8,	 /* absent on RTL-8139A */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
enum ClearBitMasks {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	MultiIntrClear	= 0xF000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	ChipCmdClear	= 0xE2,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
	Config1Clear	= (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
enum ChipCmdBits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	CmdReset	= 0x10,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
	CmdRxEnb	= 0x08,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	CmdTxEnb	= 0x04,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	RxBufEmpty	= 0x01,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
/* Interrupt register bits, using my own meaningful names. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
enum IntrStatusBits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	PCIErr		= 0x8000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	PCSTimeout	= 0x4000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	RxFIFOOver	= 0x40,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	RxUnderrun	= 0x20,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	RxOverflow	= 0x10,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	TxErr		= 0x08,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	TxOK		= 0x04,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	RxErr		= 0x02,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	RxOK		= 0x01,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	RxAckBits	= RxFIFOOver | RxOverflow | RxOK,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
enum TxStatusBits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	TxHostOwns	= 0x2000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	TxUnderrun	= 0x4000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	TxStatOK	= 0x8000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	TxOutOfWindow	= 0x20000000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	TxAborted	= 0x40000000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	TxCarrierLost	= 0x80000000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
enum RxStatusBits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	RxMulticast	= 0x8000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	RxPhysical	= 0x4000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	RxBroadcast	= 0x2000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	RxBadSymbol	= 0x0020,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	RxRunt		= 0x0010,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	RxTooLong	= 0x0008,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	RxCRCErr	= 0x0004,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	RxBadAlign	= 0x0002,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	RxStatusOK	= 0x0001,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
/* Bits in RxConfig. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
enum rx_mode_bits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
	AcceptErr	= 0x20,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	AcceptRunt	= 0x10,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	AcceptBroadcast	= 0x08,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	AcceptMulticast	= 0x04,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	AcceptMyPhys	= 0x02,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	AcceptAllPhys	= 0x01,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
/* Bits in TxConfig. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
enum tx_config_bits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
        /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
        TxIFGShift	= 24,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
        TxIFG84		= (0 << TxIFGShift), /* 8.4us / 840ns (10 / 100Mbps) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
        TxIFG88		= (1 << TxIFGShift), /* 8.8us / 880ns (10 / 100Mbps) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
        TxIFG92		= (2 << TxIFGShift), /* 9.2us / 920ns (10 / 100Mbps) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
        TxIFG96		= (3 << TxIFGShift), /* 9.6us / 960ns (10 / 100Mbps) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	TxLoopBack	= (1 << 18) | (1 << 17), /* enable loopback test mode */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	TxCRC		= (1 << 16),	/* DISABLE Tx pkt CRC append */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	TxClearAbt	= (1 << 0),	/* Clear abort (WO) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	TxDMAShift	= 8, /* DMA burst value (0-7) is shifted X many bits */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	TxRetryShift	= 4, /* TXRR value (0-15) is shifted X many bits */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	TxVersionMask	= 0x7C800000, /* mask out version bits 30-26, 23 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
/* Bits in Config1 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
enum Config1Bits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	Cfg1_PM_Enable	= 0x01,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	Cfg1_VPD_Enable	= 0x02,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	Cfg1_PIO	= 0x04,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	Cfg1_MMIO	= 0x08,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	LWAKE		= 0x10,		/* not on 8139, 8139A */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	Cfg1_Driver_Load = 0x20,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	Cfg1_LED0	= 0x40,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	Cfg1_LED1	= 0x80,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	SLEEP		= (1 << 1),	/* only on 8139, 8139A */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	PWRDN		= (1 << 0),	/* only on 8139, 8139A */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
/* Bits in Config3 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
enum Config3Bits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	Cfg3_FBtBEn   	= (1 << 0), /* 1	= Fast Back to Back */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	Cfg3_FuncRegEn	= (1 << 1), /* 1	= enable CardBus Function registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	Cfg3_CLKRUN_En	= (1 << 2), /* 1	= enable CLKRUN */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	Cfg3_CardB_En 	= (1 << 3), /* 1	= enable CardBus registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	Cfg3_LinkUp   	= (1 << 4), /* 1	= wake up on link up */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
	Cfg3_Magic    	= (1 << 5), /* 1	= wake up on Magic Packet (tm) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	Cfg3_PARM_En  	= (1 << 6), /* 0	= software can set twister parameters */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	Cfg3_GNTSel   	= (1 << 7), /* 1	= delay 1 clock from PCI GNT signal */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
/* Bits in Config4 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
enum Config4Bits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	LWPTN	= (1 << 2),	/* not on 8139, 8139A */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
/* Bits in Config5 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
enum Config5Bits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	Cfg5_PME_STS   	= (1 << 0), /* 1	= PCI reset resets PME_Status */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	Cfg5_LANWake   	= (1 << 1), /* 1	= enable LANWake signal */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	Cfg5_LDPS      	= (1 << 2), /* 0	= save power when link is down */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	Cfg5_FIFOAddrPtr= (1 << 3), /* Realtek internal SRAM testing */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	Cfg5_UWF        = (1 << 4), /* 1 = accept unicast wakeup frame */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	Cfg5_MWF        = (1 << 5), /* 1 = accept multicast wakeup frame */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	Cfg5_BWF        = (1 << 6), /* 1 = accept broadcast wakeup frame */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
enum RxConfigBits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	/* rx fifo threshold */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	RxCfgFIFOShift	= 13,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	RxCfgFIFONone	= (7 << RxCfgFIFOShift),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	/* Max DMA burst */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	RxCfgDMAShift	= 8,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	RxCfgDMAUnlimited = (7 << RxCfgDMAShift),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
	/* rx ring buffer length */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
	RxCfgRcv8K	= 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	RxCfgRcv16K	= (1 << 11),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	RxCfgRcv32K	= (1 << 12),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	RxCfgRcv64K	= (1 << 11) | (1 << 12),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	/* Disable packet wrap at end of Rx buffer. (not possible with 64k) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	RxNoWrap	= (1 << 7),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
/* Twister tuning parameters from RealTek.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
   Completely undocumented, but required to tune bad links on some boards. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
enum CSCRBits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	CSCR_LinkOKBit		= 0x0400,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	CSCR_LinkChangeBit	= 0x0800,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	CSCR_LinkStatusBits	= 0x0f000,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	CSCR_LinkDownOffCmd	= 0x003c0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	CSCR_LinkDownCmd	= 0x0f3c0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
enum Cfg9346Bits {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	Cfg9346_Lock	= 0x00,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	Cfg9346_Unlock	= 0xC0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
typedef enum {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	CH_8139	= 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	CH_8139_K,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	CH_8139A,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	CH_8139A_G,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	CH_8139B,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	CH_8130,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	CH_8139C,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	CH_8100,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	CH_8100B_8139D,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	CH_8101,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
} chip_t;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
enum chip_flags {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	HasHltClk	= (1 << 0),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	HasLWake	= (1 << 1),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	(b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
#define HW_REVID_MASK	HW_REVID(1, 1, 1, 1, 1, 1, 1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
/* directly indexed by chip_t, above */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
static const struct {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	const char *name;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	u32 version; /* from RTL8139C/RTL8139D docs */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	u32 flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
} rtl_chip_info[] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	{ "RTL-8139",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
	  HW_REVID(1, 0, 0, 0, 0, 0, 0),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	  HasHltClk,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	{ "RTL-8139 rev K",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	  HW_REVID(1, 1, 0, 0, 0, 0, 0),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	  HasHltClk,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	{ "RTL-8139A",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	  HW_REVID(1, 1, 1, 0, 0, 0, 0),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	  HasHltClk, /* XXX undocumented? */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	{ "RTL-8139A rev G",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	  HW_REVID(1, 1, 1, 0, 0, 1, 0),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
	  HasHltClk, /* XXX undocumented? */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	{ "RTL-8139B",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	  HW_REVID(1, 1, 1, 1, 0, 0, 0),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	  HasLWake,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	{ "RTL-8130",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	  HW_REVID(1, 1, 1, 1, 1, 0, 0),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	  HasLWake,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	{ "RTL-8139C",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	  HW_REVID(1, 1, 1, 0, 1, 0, 0),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	  HasLWake,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	{ "RTL-8100",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	  HW_REVID(1, 1, 1, 1, 0, 1, 0),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
 	  HasLWake,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
 	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	{ "RTL-8100B/8139D",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	  HW_REVID(1, 1, 1, 0, 1, 0, 1),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	  HasHltClk /* XXX undocumented? */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	| HasLWake,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	{ "RTL-8101",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	  HW_REVID(1, 1, 1, 0, 1, 1, 1),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	  HasLWake,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
struct rtl_extra_stats {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	unsigned long early_rx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	unsigned long tx_buf_mapped;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	unsigned long tx_timeouts;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	unsigned long rx_lost_in_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
struct rtl8139_stats {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	u64	packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	u64	bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	struct u64_stats_sync	syncp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
struct rtl8139_private {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	void __iomem		*mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	int			drv_flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	struct pci_dev		*pci_dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	u32			msg_enable;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	struct napi_struct	napi;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	struct net_device	*dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	unsigned char		*rx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	unsigned int		cur_rx;	/* RX buf index of next pkt */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	struct rtl8139_stats	rx_stats;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	dma_addr_t		rx_ring_dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	unsigned int		tx_flag;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	unsigned long		cur_tx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	unsigned long		dirty_tx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	struct rtl8139_stats	tx_stats;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	unsigned char		*tx_buf[NUM_TX_DESC];	/* Tx bounce buffers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	unsigned char		*tx_bufs;	/* Tx bounce buffer region. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	dma_addr_t		tx_bufs_dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	signed char		phys[4];	/* MII device addresses. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
				/* Twister tune state. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	char			twistie, twist_row, twist_col;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	unsigned int		watchdog_fired : 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	unsigned int		default_port : 4; /* Last dev->if_port value. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	unsigned int		have_thread : 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	spinlock_t		lock;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	spinlock_t		rx_lock;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	chip_t			chipset;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	u32			rx_config;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	struct rtl_extra_stats	xstats;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	struct delayed_work	thread;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	struct mii_if_info	mii;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	unsigned int		regs_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	unsigned long		fifo_copy_timeout;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	ec_device_t *ecdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
MODULE_LICENSE("GPL");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
MODULE_VERSION(EC_MASTER_VERSION);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
module_param(use_io, bool, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
MODULE_PARM_DESC(use_io, "Force use of I/O access mode. 0=MMIO 1=PIO");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
module_param(multicast_filter_limit, int, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
module_param_array(media, int, NULL, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
module_param_array(full_duplex, int, NULL, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
module_param(debug, int, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
MODULE_PARM_DESC (debug, "8139too bitmapped message enable number");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
void ec_poll(struct net_device *);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
static int rtl8139_open (struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
static int mdio_read (struct net_device *dev, int phy_id, int location);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
static void mdio_write (struct net_device *dev, int phy_id, int location,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
			int val);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
static void rtl8139_start_thread(struct rtl8139_private *tp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
static void rtl8139_tx_timeout (struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
static void rtl8139_init_ring (struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
				       struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
#ifdef CONFIG_NET_POLL_CONTROLLER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
static void rtl8139_poll_controller(struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
static int rtl8139_set_mac_address(struct net_device *dev, void *p);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
static int rtl8139_poll(struct napi_struct *napi, int budget);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
static int rtl8139_close (struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
static struct rtnl_link_stats64 *rtl8139_get_stats64(struct net_device *dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
						    struct rtnl_link_stats64
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
						    *stats);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
static void rtl8139_set_rx_mode (struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
static void __set_rx_mode (struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
static void rtl8139_hw_start (struct net_device *dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
static void rtl8139_thread (struct work_struct *work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
static void rtl8139_tx_timeout_task(struct work_struct *work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
static const struct ethtool_ops rtl8139_ethtool_ops;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
/* write MMIO register, with flush */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
/* Flush avoids rtl8139 bug w/ posted MMIO writes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
#define RTL_W8_F(reg, val8)	do { iowrite8 ((val8), ioaddr + (reg)); ioread8 (ioaddr + (reg)); } while (0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
#define RTL_W16_F(reg, val16)	do { iowrite16 ((val16), ioaddr + (reg)); ioread16 (ioaddr + (reg)); } while (0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
#define RTL_W32_F(reg, val32)	do { iowrite32 ((val32), ioaddr + (reg)); ioread32 (ioaddr + (reg)); } while (0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
/* write MMIO register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
#define RTL_W8(reg, val8)	iowrite8 ((val8), ioaddr + (reg))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
#define RTL_W16(reg, val16)	iowrite16 ((val16), ioaddr + (reg))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
#define RTL_W32(reg, val32)	iowrite32 ((val32), ioaddr + (reg))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
/* read MMIO register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
#define RTL_R8(reg)		ioread8 (ioaddr + (reg))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
#define RTL_R16(reg)		ioread16 (ioaddr + (reg))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
#define RTL_R32(reg)		ioread32 (ioaddr + (reg))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
static const u16 rtl8139_intr_mask =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	TxErr | TxOK | RxErr | RxOK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
static const u16 rtl8139_norx_intr_mask =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	PCIErr | PCSTimeout | RxUnderrun |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	TxErr | TxOK | RxErr ;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
#if RX_BUF_IDX == 0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
static const unsigned int rtl8139_rx_config =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	RxCfgRcv8K | RxNoWrap |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	(RX_FIFO_THRESH << RxCfgFIFOShift) |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	(RX_DMA_BURST << RxCfgDMAShift);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
#elif RX_BUF_IDX == 1
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
static const unsigned int rtl8139_rx_config =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	RxCfgRcv16K | RxNoWrap |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	(RX_FIFO_THRESH << RxCfgFIFOShift) |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	(RX_DMA_BURST << RxCfgDMAShift);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
#elif RX_BUF_IDX == 2
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
static const unsigned int rtl8139_rx_config =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	RxCfgRcv32K | RxNoWrap |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	(RX_FIFO_THRESH << RxCfgFIFOShift) |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	(RX_DMA_BURST << RxCfgDMAShift);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
#elif RX_BUF_IDX == 3
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
static const unsigned int rtl8139_rx_config =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	RxCfgRcv64K |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	(RX_FIFO_THRESH << RxCfgFIFOShift) |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	(RX_DMA_BURST << RxCfgDMAShift);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
#else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
#error "Invalid configuration for 8139_RXBUF_IDX"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
static const unsigned int rtl8139_tx_config =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	TxIFG96 | (TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
static void __rtl8139_cleanup_dev (struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	struct pci_dev *pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	assert (dev != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	assert (tp->pci_dev != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	pdev = tp->pci_dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	if (tp->mmio_addr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		pci_iounmap (pdev, tp->mmio_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	/* it's ok to call this even if we have no regions to free */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	pci_release_regions (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	free_netdev(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	pci_set_drvdata (pdev, NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
static void rtl8139_chip_reset (void __iomem *ioaddr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	/* Soft reset the chip. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	RTL_W8 (ChipCmd, CmdReset);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	/* Check that the chip has finished the reset. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	for (i = 1000; i > 0; i--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
		barrier();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
		udelay (10);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
static struct net_device *rtl8139_init_board(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	struct device *d = &pdev->dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	void __iomem *ioaddr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	struct net_device *dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	struct rtl8139_private *tp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	u8 tmp8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	int rc, disable_dev_on_err = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	unsigned int i, bar;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	unsigned long io_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	u32 version;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	static const struct {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		unsigned long mask;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
		char *type;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	} res[] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
		{ IORESOURCE_IO,  "PIO" },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
		{ IORESOURCE_MEM, "MMIO" }
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	assert (pdev != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	/* dev and priv zeroed in alloc_etherdev */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	dev = alloc_etherdev (sizeof (*tp));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	if (dev == NULL)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		return ERR_PTR(-ENOMEM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	SET_NETDEV_DEV(dev, &pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	tp->pci_dev = pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	/* enable device (incl. PCI PM wakeup and hotplug setup) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	rc = pci_enable_device (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	if (rc)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
		goto err_out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	rc = pci_request_regions (pdev, DRV_NAME);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	if (rc)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		goto err_out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	disable_dev_on_err = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	pci_set_master (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
retry:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	/* PIO bar register comes first. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	bar = !use_io;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	io_len = pci_resource_len(pdev, bar);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	dev_dbg(d, "%s region size = 0x%02lX\n", res[bar].type, io_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	if (!(pci_resource_flags(pdev, bar) & res[bar].mask)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
		dev_err(d, "region #%d not a %s resource, aborting\n", bar,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
			res[bar].type);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
		rc = -ENODEV;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
		goto err_out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	if (io_len < RTL_MIN_IO_SIZE) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		dev_err(d, "Invalid PCI %s region size(s), aborting\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
			res[bar].type);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
		rc = -ENODEV;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
		goto err_out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	ioaddr = pci_iomap(pdev, bar, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	if (!ioaddr) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
		dev_err(d, "cannot map %s\n", res[bar].type);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		if (!use_io) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
			use_io = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
			goto retry;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		rc = -ENODEV;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		goto err_out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	tp->regs_len = io_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	tp->mmio_addr = ioaddr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	/* Bring old chips out of low-power mode. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	RTL_W8 (HltClk, 'R');
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	/* check for missing/broken hardware */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	if (RTL_R32 (TxConfig) == 0xFFFFFFFF) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		dev_err(&pdev->dev, "Chip not responding, ignoring board\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		rc = -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		goto err_out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	/* identify chip attached to board */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	version = RTL_R32 (TxConfig) & HW_REVID_MASK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	for (i = 0; i < ARRAY_SIZE (rtl_chip_info); i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		if (version == rtl_chip_info[i].version) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
			tp->chipset = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
			goto match;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	/* if unknown chip, assume array element #0, original RTL-8139 in this case */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	dev_dbg(&pdev->dev, "TxConfig = 0x%x\n", RTL_R32 (TxConfig));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	tp->chipset = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
match:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	pr_debug("chipset id (%d) == index %d, '%s'\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		 version, i, rtl_chip_info[i].name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	if (tp->chipset >= CH_8139B) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
		u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		pr_debug("PCI PM wakeup\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
		if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
		    (tmp8 & LWAKE))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
			new_tmp8 &= ~LWAKE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
		new_tmp8 |= Cfg1_PM_Enable;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
		if (new_tmp8 != tmp8) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
			RTL_W8 (Cfg9346, Cfg9346_Unlock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
			RTL_W8 (Config1, tmp8);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
			RTL_W8 (Cfg9346, Cfg9346_Lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
		if (rtl_chip_info[tp->chipset].flags & HasLWake) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
			tmp8 = RTL_R8 (Config4);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
			if (tmp8 & LWPTN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
				RTL_W8 (Cfg9346, Cfg9346_Unlock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
				RTL_W8 (Config4, tmp8 & ~LWPTN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
				RTL_W8 (Cfg9346, Cfg9346_Lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
		pr_debug("Old chip wakeup\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
		tmp8 = RTL_R8 (Config1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
		tmp8 &= ~(SLEEP | PWRDN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
		RTL_W8 (Config1, tmp8);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	rtl8139_chip_reset (ioaddr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
	return dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
err_out:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	__rtl8139_cleanup_dev (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	if (disable_dev_on_err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		pci_disable_device (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	return ERR_PTR(rc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
static int rtl8139_set_features(struct net_device *dev, netdev_features_t features)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	unsigned long flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	netdev_features_t changed = features ^ dev->features;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	if (!(changed & (NETIF_F_RXALL)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	spin_lock_irqsave(&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	if (changed & NETIF_F_RXALL) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
		int rx_mode = tp->rx_config;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
		if (features & NETIF_F_RXALL)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
			rx_mode |= (AcceptErr | AcceptRunt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
			rx_mode &= ~(AcceptErr | AcceptRunt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
		tp->rx_config = rtl8139_rx_config | rx_mode;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
		RTL_W32_F(RxConfig, tp->rx_config);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	spin_unlock_irqrestore(&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
static const struct net_device_ops rtl8139_netdev_ops = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	.ndo_open		= rtl8139_open,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	.ndo_stop		= rtl8139_close,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	.ndo_get_stats64	= rtl8139_get_stats64,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	.ndo_change_mtu		= eth_change_mtu,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	.ndo_validate_addr	= eth_validate_addr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	.ndo_set_mac_address 	= rtl8139_set_mac_address,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	.ndo_start_xmit		= rtl8139_start_xmit,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	.ndo_set_rx_mode	= rtl8139_set_rx_mode,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	.ndo_do_ioctl		= netdev_ioctl,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	.ndo_tx_timeout		= rtl8139_tx_timeout,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
#ifdef CONFIG_NET_POLL_CONTROLLER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	.ndo_poll_controller	= rtl8139_poll_controller,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	.ndo_set_features	= rtl8139_set_features,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
static int rtl8139_init_one(struct pci_dev *pdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
			    const struct pci_device_id *ent)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	struct net_device *dev = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	struct rtl8139_private *tp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	int i, addr_len, option;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	void __iomem *ioaddr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	static int board_idx = -1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	assert (pdev != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	assert (ent != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	board_idx++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	/* when we're built into the kernel, the driver version message
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	 * is only printed if at least one 8139 board has been found
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
#ifndef MODULE
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		static int printed_version;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
		if (!printed_version++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
			pr_info(RTL8139_DRIVER_NAME "\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision >= 0x20) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		dev_info(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
			   "This (id %04x:%04x rev %02x) is an enhanced 8139C+ chip, use 8139cp\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		       	   pdev->vendor, pdev->device, pdev->revision);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
		return -ENODEV;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	    pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	    pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		pr_info("OQO Model 2 detected. Forcing PIO\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
		use_io = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
	dev = rtl8139_init_board (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	if (IS_ERR(dev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		return PTR_ERR(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	assert (dev != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	tp->dev = dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	assert (ioaddr != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	for (i = 0; i < 3; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		((__le16 *) (dev->dev_addr))[i] =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		    cpu_to_le16(read_eeprom (ioaddr, i + 7, addr_len));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	/* The Rtl8139-specific entries in the device structure. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	dev->netdev_ops = &rtl8139_netdev_ops;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	dev->ethtool_ops = &rtl8139_ethtool_ops;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	dev->watchdog_timeo = TX_TIMEOUT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	/* note: the hardware is not capable of sg/csum/highdma, however
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	 * through the use of skb_copy_and_csum_dev we enable these
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	 * features
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	dev->vlan_features = dev->features;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	dev->hw_features |= NETIF_F_RXALL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	dev->hw_features |= NETIF_F_RXFCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	/* tp zeroed and aligned in alloc_etherdev */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	/* note: tp->chipset set in rtl8139_init_board */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
	tp->drv_flags = board_info[ent->driver_data].hw_flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	tp->mmio_addr = ioaddr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	tp->msg_enable =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		(debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	spin_lock_init (&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	spin_lock_init (&tp->rx_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	tp->mii.dev = dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	tp->mii.mdio_read = mdio_read;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	tp->mii.mdio_write = mdio_write;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	tp->mii.phy_id_mask = 0x3f;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	tp->mii.reg_num_mask = 0x1f;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	/* dev is fully set up and ready to use now */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	// offer device to EtherCAT master module
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	tp->ecdev = ecdev_offer(dev, ec_poll, THIS_MODULE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
		pr_debug("about to register device named %s (%p)...\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
				dev->name, dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		i = register_netdev (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		if (i) goto err_out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	pci_set_drvdata (pdev, dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
	pr_info("%s: %s at 0x%lx, %pM, IRQ %d\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		dev->name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		board_info[ent->driver_data].name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		dev->base_addr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		dev->dev_addr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		dev->irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	pr_debug("%s:  Identified 8139 chip type '%s'\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		dev->name, rtl_chip_info[tp->chipset].name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	/* Find the connected MII xcvrs.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	   Doing this in open() would allow detecting external xcvrs later, but
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	   takes too much time. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
#ifdef CONFIG_8139TOO_8129
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	if (tp->drv_flags & HAS_MII_XCVR) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
		int phy, phy_idx = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		for (phy = 0; phy < 32 && phy_idx < sizeof(tp->phys); phy++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
			int mii_status = mdio_read(dev, phy, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
				u16 advertising = mdio_read(dev, phy, 4);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
				tp->phys[phy_idx++] = phy;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
				pr_info("%s: MII transceiver %d status 0x%4.4x advertising %4.4x.\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
					   dev->name, phy, mii_status, advertising);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
		if (phy_idx == 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			pr_info("%s: No MII transceivers found! Assuming SYM transceiver.\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
				   dev->name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			tp->phys[0] = 32;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	} else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		tp->phys[0] = 32;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	tp->mii.phy_id = tp->phys[0];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
	/* The lower four bits are the media type. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
	option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	if (option > 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		tp->mii.full_duplex = (option & 0x210) ? 1 : 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		tp->default_port = option & 0xFF;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		if (tp->default_port)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
			tp->mii.force_media = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
	if (board_idx < MAX_UNITS  &&  full_duplex[board_idx] > 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
		tp->mii.full_duplex = full_duplex[board_idx];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	if (tp->mii.full_duplex) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		pr_info("%s: Media type forced to Full Duplex.\n", dev->name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
		/* Changing the MII-advertised media because might prevent
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
		   re-connection. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		tp->mii.force_media = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
	if (tp->default_port) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		pr_info("  Forcing %dMbps %s-duplex operation.\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
			   (option & 0x20 ? 100 : 10),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
			   (option & 0x10 ? "full" : "half"));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		mdio_write(dev, tp->phys[0], 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
				   ((option & 0x20) ? 0x2000 : 0) | 	/* 100Mbps? */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
				   ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	/* Put the chip into low-power mode. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	if (tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
		i = ecdev_open(tp->ecdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		if (i) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
			ecdev_withdraw(tp->ecdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
			goto err_out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
err_out:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	__rtl8139_cleanup_dev (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	pci_disable_device (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
	return i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
static void rtl8139_remove_one(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	struct net_device *dev = pci_get_drvdata (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	assert (dev != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	if (tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
		ecdev_close(tp->ecdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
		ecdev_withdraw(tp->ecdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		cancel_delayed_work_sync(&tp->thread);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
		unregister_netdev (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	__rtl8139_cleanup_dev (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	pci_disable_device (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
/* Serial EEPROM section. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
/*  EEPROM_Ctrl bits. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
#define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
#define EE_CS			0x08	/* EEPROM chip select. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
#define EE_DATA_WRITE	0x02	/* EEPROM chip data in. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
#define EE_WRITE_0		0x00
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
#define EE_WRITE_1		0x02
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
#define EE_DATA_READ	0x01	/* EEPROM chip data out. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
#define EE_ENB			(0x80 | EE_CS)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
/* Delay between EEPROM clock transitions.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
   No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
#define eeprom_delay()	(void)RTL_R8(Cfg9346)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
/* The EEPROM commands include the alway-set leading bit. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
#define EE_WRITE_CMD	(5)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
#define EE_READ_CMD		(6)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
#define EE_ERASE_CMD	(7)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
static int read_eeprom(void __iomem *ioaddr, int location, int addr_len)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	unsigned retval = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	int read_cmd = location | (EE_READ_CMD << addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	RTL_W8 (Cfg9346, EE_ENB & ~EE_CS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	RTL_W8 (Cfg9346, EE_ENB);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	eeprom_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
	/* Shift the read command bits out. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
	for (i = 4 + addr_len; i >= 0; i--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		RTL_W8 (Cfg9346, EE_ENB | dataval);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
		eeprom_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		RTL_W8 (Cfg9346, EE_ENB | dataval | EE_SHIFT_CLK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		eeprom_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	RTL_W8 (Cfg9346, EE_ENB);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	eeprom_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	for (i = 16; i > 0; i--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		RTL_W8 (Cfg9346, EE_ENB | EE_SHIFT_CLK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		eeprom_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
		retval =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
		    (retval << 1) | ((RTL_R8 (Cfg9346) & EE_DATA_READ) ? 1 :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
				     0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
		RTL_W8 (Cfg9346, EE_ENB);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
		eeprom_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	/* Terminate the EEPROM access. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	RTL_W8(Cfg9346, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	eeprom_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
/* MII serial management: mostly bogus for now. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
/* Read and write the MII management registers using software-generated
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
   serial MDIO protocol.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
   The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
   "overclocking" issues. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
#define MDIO_DIR		0x80
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
#define MDIO_DATA_OUT	0x04
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
#define MDIO_DATA_IN	0x02
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
#define MDIO_CLK		0x01
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
#define MDIO_WRITE0 (MDIO_DIR)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
#define mdio_delay()	RTL_R8(Config4)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
static const char mii_2_8139_map[8] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	BasicModeCtrl,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	BasicModeStatus,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	NWayAdvert,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	NWayLPAR,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	NWayExpansion,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
#ifdef CONFIG_8139TOO_8129
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
/* Syncronize the MII management interface by shifting 32 one bits out. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
static void mdio_sync (void __iomem *ioaddr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
	for (i = 32; i >= 0; i--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		RTL_W8 (Config4, MDIO_WRITE1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		RTL_W8 (Config4, MDIO_WRITE1 | MDIO_CLK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
static int mdio_read (struct net_device *dev, int phy_id, int location)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	int retval = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
#ifdef CONFIG_8139TOO_8129
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
		void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
		return location < 8 && mii_2_8139_map[location] ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
		    RTL_R16 (mii_2_8139_map[location]) : 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
#ifdef CONFIG_8139TOO_8129
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
	mdio_sync (ioaddr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
	/* Shift the read command bits out. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	for (i = 15; i >= 0; i--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
		int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
		RTL_W8 (Config4, MDIO_DIR | dataval);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
		RTL_W8 (Config4, MDIO_DIR | dataval | MDIO_CLK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	/* Read the two transition, 16 data, and wire-idle bits. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	for (i = 19; i > 0; i--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
		RTL_W8 (Config4, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		retval = (retval << 1) | ((RTL_R8 (Config4) & MDIO_DATA_IN) ? 1 : 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
		RTL_W8 (Config4, MDIO_CLK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
	return (retval >> 1) & 0xffff;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
static void mdio_write (struct net_device *dev, int phy_id, int location,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
			int value)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
#ifdef CONFIG_8139TOO_8129
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
		void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
		if (location == 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
			RTL_W8 (Cfg9346, Cfg9346_Unlock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
			RTL_W16 (BasicModeCtrl, value);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
			RTL_W8 (Cfg9346, Cfg9346_Lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
		} else if (location < 8 && mii_2_8139_map[location])
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
			RTL_W16 (mii_2_8139_map[location], value);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
#ifdef CONFIG_8139TOO_8129
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	mdio_sync (ioaddr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	/* Shift the command bits out. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	for (i = 31; i >= 0; i--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
		int dataval =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
		    (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
		RTL_W8 (Config4, dataval);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
		RTL_W8 (Config4, dataval | MDIO_CLK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	/* Clear out extra bits. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	for (i = 2; i > 0; i--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
		RTL_W8 (Config4, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
		RTL_W8 (Config4, MDIO_CLK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
		mdio_delay ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
static int rtl8139_open (struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	const int irq = tp->pci_dev->irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	int retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
		retval = request_irq(irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
		if (retval)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
			return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	tp->tx_bufs = dma_alloc_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
					   &tp->tx_bufs_dma, GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	tp->rx_ring = dma_alloc_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
					   &tp->rx_ring_dma, GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
	if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
			free_irq(irq, dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		if (tp->tx_bufs)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
			dma_free_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
					    tp->tx_bufs, tp->tx_bufs_dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		if (tp->rx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
			dma_free_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
					    tp->rx_ring, tp->rx_ring_dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	napi_enable(&tp->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	tp->mii.full_duplex = tp->mii.force_media;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	rtl8139_init_ring (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	rtl8139_hw_start (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
		netif_start_queue (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	netif_dbg(tp, ifup, dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
		  "%s() ioaddr %#llx IRQ %d GP Pins %02x %s-duplex\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
		  __func__,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
		  (unsigned long long)pci_resource_start (tp->pci_dev, 1),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
		  irq, RTL_R8 (MediaStatus),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
		  tp->mii.full_duplex ? "full" : "half");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		rtl8139_start_thread(tp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
static void rtl_check_media (struct net_device *dev, unsigned int init_media)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	if (tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
		void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		u16 state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		ecdev_set_link(tp->ecdev, state ? 1 : 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
		if (tp->phys[0] >= 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
			mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
/* Start the hardware at open or resume. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
static void rtl8139_hw_start (struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	u32 i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	u8 tmp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	/* Bring old chips out of low-power mode. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
		RTL_W8 (HltClk, 'R');
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	rtl8139_chip_reset (ioaddr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	/* unlock Config[01234] and BMCR register writes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	/* Restore our idea of the MAC address. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
	RTL_W32_F (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	RTL_W32_F (MAC0 + 4, le16_to_cpu (*(__le16 *) (dev->dev_addr + 4)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	tp->cur_rx = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	/* init Rx ring buffer DMA address */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	RTL_W32_F (RxBuf, tp->rx_ring_dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	/* Must enable Tx/Rx before setting transfer thresholds! */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	RTL_W32 (RxConfig, tp->rx_config);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	RTL_W32 (TxConfig, rtl8139_tx_config);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	rtl_check_media (dev, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
	if (tp->chipset >= CH_8139B) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
		/* Disable magic packet scanning, which is enabled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		 * when PM is enabled in Config1.  It can be reenabled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		 * via ETHTOOL_SWOL if desired.  */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
		RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	netdev_dbg(dev, "init buffer addresses\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	/* Lock Config[01234] and BMCR register writes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	RTL_W8 (Cfg9346, Cfg9346_Lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	/* init Tx buffer DMA addresses */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	for (i = 0; i < NUM_TX_DESC; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	RTL_W32 (RxMissed, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	rtl8139_set_rx_mode (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	/* no early-rx interrupts */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	RTL_W16 (MultiIntr, RTL_R16 (MultiIntr) & MultiIntrClear);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
	/* make sure RxTx has started */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	tmp = RTL_R8 (ChipCmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
		/* Enable all known interrupts by setting the interrupt mask. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		RTL_W16 (IntrMask, rtl8139_intr_mask);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
static void rtl8139_init_ring (struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	tp->cur_rx = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	tp->cur_tx = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	tp->dirty_tx = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	for (i = 0; i < NUM_TX_DESC; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		tp->tx_buf[i] = &tp->tx_bufs[i * TX_BUF_SIZE];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
/* This must be global for CONFIG_8139TOO_TUNE_TWISTER case */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
static int next_tick = 3 * HZ;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
#ifndef CONFIG_8139TOO_TUNE_TWISTER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
static inline void rtl8139_tune_twister (struct net_device *dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
				  struct rtl8139_private *tp) {}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
#else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
enum TwisterParamVals {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	PARA78_default	= 0x78fa8388,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
	PARA7c_default	= 0xcb38de43,	/* param[0][3] */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	PARA7c_xxx	= 0xcb38de43,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
static const unsigned long param[4][4] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	{0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	{0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
static void rtl8139_tune_twister (struct net_device *dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
				  struct rtl8139_private *tp)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
	int linkcase;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	/* This is a complicated state machine to configure the "twister" for
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	   impedance/echos based on the cable length.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	   All of this is magic and undocumented.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	switch (tp->twistie) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	case 1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
		if (RTL_R16 (CSCR) & CSCR_LinkOKBit) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
			/* We have link beat, let us tune the twister. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
			RTL_W16 (CSCR, CSCR_LinkDownOffCmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
			tp->twistie = 2;	/* Change to state 2. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
			next_tick = HZ / 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
			/* Just put in some reasonable defaults for when beat returns. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
			RTL_W16 (CSCR, CSCR_LinkDownCmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
			RTL_W32 (FIFOTMS, 0x20);	/* Turn on cable test mode. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
			RTL_W32 (PARA78, PARA78_default);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
			RTL_W32 (PARA7c, PARA7c_default);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
			tp->twistie = 0;	/* Bail from future actions. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	case 2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
		/* Read how long it took to hear the echo. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
		linkcase = RTL_R16 (CSCR) & CSCR_LinkStatusBits;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
		if (linkcase == 0x7000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
			tp->twist_row = 3;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		else if (linkcase == 0x3000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
			tp->twist_row = 2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		else if (linkcase == 0x1000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
			tp->twist_row = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
			tp->twist_row = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		tp->twist_col = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		tp->twistie = 3;	/* Change to state 2. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
		next_tick = HZ / 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	case 3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		/* Put out four tuning parameters, one per 100msec. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		if (tp->twist_col == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
			RTL_W16 (FIFOTMS, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		RTL_W32 (PARA7c, param[(int) tp->twist_row]
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
			 [(int) tp->twist_col]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		next_tick = HZ / 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
		if (++tp->twist_col >= 4) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
			/* For short cables we are done.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
			   For long cables (row == 3) check for mistune. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
			tp->twistie =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
			    (tp->twist_row == 3) ? 4 : 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	case 4:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
		/* Special case for long cables: check for mistune. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		if ((RTL_R16 (CSCR) &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		     CSCR_LinkStatusBits) == 0x7000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
			tp->twistie = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
			RTL_W32 (PARA7c, 0xfb38de03);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
			tp->twistie = 5;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
			next_tick = HZ / 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	case 5:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		/* Retune for shorter cable (column 2). */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		RTL_W32 (FIFOTMS, 0x20);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		RTL_W32 (PARA78, PARA78_default);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		RTL_W32 (PARA7c, PARA7c_default);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		RTL_W32 (FIFOTMS, 0x00);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		tp->twist_row = 2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		tp->twist_col = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		tp->twistie = 3;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		next_tick = HZ / 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		/* do nothing */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
#endif /* CONFIG_8139TOO_TUNE_TWISTER */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
static inline void rtl8139_thread_iter (struct net_device *dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
				 struct rtl8139_private *tp,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
				 void __iomem *ioaddr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	int mii_lpa;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	mii_lpa = mdio_read (dev, tp->phys[0], MII_LPA);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	if (!tp->mii.force_media && mii_lpa != 0xffff) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		int duplex = ((mii_lpa & LPA_100FULL) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
			      (mii_lpa & 0x01C0) == 0x0040);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
		if (tp->mii.full_duplex != duplex) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
			tp->mii.full_duplex = duplex;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
			if (mii_lpa) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
				netdev_info(dev, "Setting %s-duplex based on MII #%d link partner ability of %04x\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
					    tp->mii.full_duplex ? "full" : "half",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
					    tp->phys[0], mii_lpa);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
				netdev_info(dev, "media is unconnected, link down, or incompatible connection\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
#if 0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
			RTL_W8 (Cfg9346, Cfg9346_Unlock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
			RTL_W8 (Config1, tp->mii.full_duplex ? 0x60 : 0x20);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
			RTL_W8 (Cfg9346, Cfg9346_Lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	next_tick = HZ * 60;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	rtl8139_tune_twister (dev, tp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	netdev_dbg(dev, "Media selection tick, Link partner %04x\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		   RTL_R16(NWayLPAR));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	netdev_dbg(dev, "Other registers are IntMask %04x IntStatus %04x\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
		   RTL_R16(IntrMask), RTL_R16(IntrStatus));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	netdev_dbg(dev, "Chip config %02x %02x\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
		   RTL_R8(Config0), RTL_R8(Config1));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
static void rtl8139_thread (struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	struct rtl8139_private *tp =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		container_of(work, struct rtl8139_private, thread.work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	struct net_device *dev = tp->mii.dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	unsigned long thr_delay = next_tick;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	rtnl_lock();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	if (!netif_running(dev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		goto out_unlock;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	if (tp->watchdog_fired) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		tp->watchdog_fired = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
		rtl8139_tx_timeout_task(work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	} else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
		rtl8139_thread_iter(dev, tp, tp->mmio_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
	if (tp->have_thread)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
		schedule_delayed_work(&tp->thread, thr_delay);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
out_unlock:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	rtnl_unlock ();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
static void rtl8139_start_thread(struct rtl8139_private *tp)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	tp->twistie = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	if (tp->chipset == CH_8139_K)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
		tp->twistie = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	else if (tp->drv_flags & HAS_LNK_CHNG)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	tp->have_thread = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	tp->watchdog_fired = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	schedule_delayed_work(&tp->thread, next_tick);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	tp->cur_tx = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	tp->dirty_tx = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	/* XXX account for unsent Tx packets in tp->stats.tx_dropped */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
static void rtl8139_tx_timeout_task (struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
	struct rtl8139_private *tp =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		container_of(work, struct rtl8139_private, thread.work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
	struct net_device *dev = tp->mii.dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	u8 tmp8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
	netdev_dbg(dev, "Transmit timeout, status %02x %04x %04x media %02x\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		   RTL_R8(ChipCmd), RTL_R16(IntrStatus),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
		   RTL_R16(IntrMask), RTL_R8(MediaStatus));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	/* Emit info to figure out what went wrong. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	netdev_dbg(dev, "Tx queue start entry %ld  dirty entry %ld\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		   tp->cur_tx, tp->dirty_tx);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	for (i = 0; i < NUM_TX_DESC; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		netdev_dbg(dev, "Tx descriptor %d is %08x%s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
			   i, RTL_R32(TxStatus0 + (i * 4)),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
			   i == tp->dirty_tx % NUM_TX_DESC ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
			   " (queue head)" : "");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	tp->xstats.tx_timeouts++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	/* disable Tx ASAP, if not already */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	tmp8 = RTL_R8 (ChipCmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	if (tmp8 & CmdTxEnb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		RTL_W8 (ChipCmd, CmdRxEnb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	if (tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		rtl8139_tx_clear (tp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		rtl8139_hw_start (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
	else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
		spin_lock_bh(&tp->rx_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		/* Disable interrupts by clearing the interrupt mask. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		RTL_W16 (IntrMask, 0x0000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		/* Stop a shared interrupt from scavenging while we are. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		spin_lock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		rtl8139_tx_clear (tp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		spin_unlock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		/* ...and finally, reset everything */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		if (netif_running(dev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
			rtl8139_hw_start (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
			netif_wake_queue (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		spin_unlock_bh(&tp->rx_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
static void rtl8139_tx_timeout (struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	tp->watchdog_fired = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
	if (!tp->ecdev && !tp->have_thread) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
		INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
		schedule_delayed_work(&tp->thread, next_tick);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
					     struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	unsigned int entry;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	unsigned int len = skb->len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	unsigned long flags = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	/* Calculate the next Tx descriptor entry. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	entry = tp->cur_tx % NUM_TX_DESC;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	/* Note: the chip doesn't have auto-pad! */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
	if (likely(len < TX_BUF_SIZE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		if (len < ETH_ZLEN)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
			memset(tp->tx_buf[entry], 0, ETH_ZLEN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
			dev_kfree_skb(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
		if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
			dev_kfree_skb(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
		dev->stats.tx_dropped++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
		return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		spin_lock_irqsave(&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
	/*
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	 * Writing to TxStatus triggers a DMA transfer of the data
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
	 * copied to tp->tx_buf[entry] above. Use a memory barrier
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	 * to make sure that the device sees the updated data.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
		   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
	tp->cur_tx++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
			netif_stop_queue (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
		spin_unlock_irqrestore(&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	netif_dbg(tp, tx_queued, dev, "Queued Tx packet size %u to slot %d\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
		  len, entry);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
	return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
static void rtl8139_tx_interrupt (struct net_device *dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
				  struct rtl8139_private *tp,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
				  void __iomem *ioaddr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	unsigned long dirty_tx, tx_left;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	assert (dev != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
	assert (ioaddr != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	dirty_tx = tp->dirty_tx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	tx_left = tp->cur_tx - dirty_tx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	while (tx_left > 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
		int entry = dirty_tx % NUM_TX_DESC;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		int txstatus;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
		txstatus = RTL_R32 (TxStatus0 + (entry * sizeof (u32)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
		if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
			break;	/* It still hasn't been Txed */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
		/* Note: TxCarrierLost is always asserted at 100mbps. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		if (txstatus & (TxOutOfWindow | TxAborted)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
			/* There was an major error, log it. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
			netif_dbg(tp, tx_err, dev, "Transmit error, Tx status %08x\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
				  txstatus);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
			dev->stats.tx_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
			if (txstatus & TxAborted) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
				dev->stats.tx_aborted_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
				RTL_W32 (TxConfig, TxClearAbt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
				RTL_W16 (IntrStatus, TxErr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
				wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
			if (txstatus & TxCarrierLost)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
				dev->stats.tx_carrier_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
			if (txstatus & TxOutOfWindow)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
				dev->stats.tx_window_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
			if (txstatus & TxUnderrun) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
				/* Add 64 to the Tx FIFO threshold. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
				if (tp->tx_flag < 0x00300000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
					tp->tx_flag += 0x00020000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
				dev->stats.tx_fifo_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
			dev->stats.collisions += (txstatus >> 24) & 15;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
			u64_stats_update_begin(&tp->tx_stats.syncp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
			tp->tx_stats.packets++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
			tp->tx_stats.bytes += txstatus & 0x7ff;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
			u64_stats_update_end(&tp->tx_stats.syncp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
		dirty_tx++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
		tx_left--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
#ifndef RTL8139_NDEBUG
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
		pr_err("%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
		        dev->name, dirty_tx, tp->cur_tx);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
		dirty_tx += NUM_TX_DESC;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
#endif /* RTL8139_NDEBUG */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	/* only wake the queue if we did work, and the queue is stopped */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	if (tp->dirty_tx != dirty_tx) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
		tp->dirty_tx = dirty_tx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
		mb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
		if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
			netif_wake_queue (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
/* TODO: clean this up!  Rx reset need not be this intensive */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
			    struct rtl8139_private *tp, void __iomem *ioaddr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	u8 tmp8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
#ifdef CONFIG_8139_OLD_RX_RESET
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	int tmp_work;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	if (netif_msg_rx_err (tp))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
		pr_debug("%s: Ethernet frame had errors, status %8.8x.\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
			dev->name, rx_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	dev->stats.rx_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
	if (!(rx_status & RxStatusOK)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
		if (rx_status & RxTooLong) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
			pr_debug("%s: Oversized Ethernet frame, status %4.4x!\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
			 	dev->name, rx_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
			/* A.C.: The chip hangs here. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		if (rx_status & (RxBadSymbol | RxBadAlign))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
			dev->stats.rx_frame_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
		if (rx_status & (RxRunt | RxTooLong))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
			dev->stats.rx_length_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
		if (rx_status & RxCRCErr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
			dev->stats.rx_crc_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		tp->xstats.rx_lost_in_ring++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
#ifndef CONFIG_8139_OLD_RX_RESET
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
	tmp8 = RTL_R8 (ChipCmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
	RTL_W8 (ChipCmd, tmp8 & ~CmdRxEnb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	RTL_W8 (ChipCmd, tmp8);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	RTL_W32 (RxConfig, tp->rx_config);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	tp->cur_rx = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
#else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
	/* Reset the receiver, based on RealTek recommendation. (Bug?) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
	/* disable receive */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
	RTL_W8_F (ChipCmd, CmdTxEnb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	tmp_work = 200;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
	while (--tmp_work > 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		udelay(1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
		tmp8 = RTL_R8 (ChipCmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
		if (!(tmp8 & CmdRxEnb))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
	if (tmp_work <= 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		pr_warning(PFX "rx stop wait too long\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
	/* restart receive */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	tmp_work = 200;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	while (--tmp_work > 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
		RTL_W8_F (ChipCmd, CmdRxEnb | CmdTxEnb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
		udelay(1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
		tmp8 = RTL_R8 (ChipCmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
		if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
	if (tmp_work <= 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
		pr_warning(PFX "tx/rx enable wait too long\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	/* and reinitialize all rx related registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	/* Must enable Tx/Rx before setting transfer thresholds! */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	RTL_W32 (RxConfig, tp->rx_config);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	tp->cur_rx = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	pr_debug("init buffer addresses\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	/* Lock Config[01234] and BMCR register writes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	RTL_W8 (Cfg9346, Cfg9346_Lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	/* init Rx ring buffer DMA address */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	RTL_W32_F (RxBuf, tp->rx_ring_dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	/* A.C.: Reset the multicast list. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	__set_rx_mode (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
#if RX_BUF_IDX == 3
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
static inline void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
				 u32 offset, unsigned int size)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	u32 left = RX_BUF_LEN - offset;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	if (size > left) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
		skb_copy_to_linear_data(skb, ring + offset, left);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
		skb_copy_to_linear_data_offset(skb, left, ring, size - left);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	} else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
		skb_copy_to_linear_data(skb, ring + offset, size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
static void rtl8139_isr_ack(struct rtl8139_private *tp)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	u16 status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	status = RTL_R16 (IntrStatus) & RxAckBits;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	/* Clear out errors and receive interrupts */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	if (likely(status != 0)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
		if (unlikely(status & (RxFIFOOver | RxOverflow))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
			tp->dev->stats.rx_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
			if (status & RxFIFOOver)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
				tp->dev->stats.rx_fifo_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		RTL_W16_F (IntrStatus, RxAckBits);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
		      int budget)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
	int received = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
	unsigned char *rx_ring = tp->rx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
	unsigned int cur_rx = tp->cur_rx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
	unsigned int rx_size = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	pr_debug("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
		 " free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		 RTL_R16 (RxBufAddr),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
	while ((tp->ecdev || netif_running(dev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			&& received < budget
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
			&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
		u32 ring_offset = cur_rx % RX_BUF_LEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
		u32 rx_status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
		unsigned int pkt_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
		struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
		rmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
		/* read size+status of next frame from DMA ring buffer */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
		rx_status = le32_to_cpu (*(__le32 *) (rx_ring + ring_offset));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
		rx_size = rx_status >> 16;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
		if (likely(!(dev->features & NETIF_F_RXFCS)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
			pkt_size = rx_size - 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
			pkt_size = rx_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
		if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
			if (netif_msg_rx_status(tp))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
				pr_debug("%s:  rtl8139_rx() status %4.4x, size %4.4x,"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
					" cur %4.4x.\n", dev->name, rx_status,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
				 rx_size, cur_rx);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
#if RTL8139_DEBUG > 2
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
		{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
			int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
			pr_debug("%s: Frame contents ", dev->name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
			for (i = 0; i < 70; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
				pr_cont(" %2.2x",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
					rx_ring[ring_offset + i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
			pr_cont(".\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
		/* Packet copy from FIFO still in progress.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
		 * Theoretically, this should never happen
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
		 * since EarlyRx is disabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
		if (unlikely(rx_size == 0xfff0)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
			if (!tp->fifo_copy_timeout)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
				tp->fifo_copy_timeout = jiffies + 2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
			else if (time_after(jiffies, tp->fifo_copy_timeout)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
				pr_debug("%s: hung FIFO. Reset.", dev->name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
				rx_size = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
				goto no_early_rx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
			if (netif_msg_intr(tp)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
				pr_debug("%s: fifo copy in progress.",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
				       dev->name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
			tp->xstats.early_rx++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
no_early_rx:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
		tp->fifo_copy_timeout = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
		/* If Rx err or invalid rx_size/rx_status received
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
		 * (which happens if we get lost in the ring),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
		 * Rx process gets reset, so we abort any further
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
		 * Rx processing.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		if (unlikely((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
			     (rx_size < 8) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
			     (!(rx_status & RxStatusOK)))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
			if ((dev->features & NETIF_F_RXALL) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
			    (rx_size <= (MAX_ETH_FRAME_SIZE + 4)) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
			    (rx_size >= 8) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
			    (!(rx_status & RxStatusOK))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
				/* Length is at least mostly OK, but pkt has
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
				 * error.  I'm hoping we can handle some of these
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
				 * errors without resetting the chip. --Ben
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
				 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
				dev->stats.rx_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
				if (rx_status & RxCRCErr) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
					dev->stats.rx_crc_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
					goto keep_pkt;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
				if (rx_status & RxRunt) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
					dev->stats.rx_length_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
					goto keep_pkt;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
			rtl8139_rx_err (rx_status, dev, tp, ioaddr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
			received = -1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
			goto out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
keep_pkt:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
		/* Malloc up new buffer, compatible with net-2e. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
		/* Omit the four octet CRC from the length. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
		if (tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
			ecdev_receive(tp->ecdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
					&rx_ring[ring_offset + 4], pkt_size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
					dev->last_rx = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
					dev->stats.rx_bytes += pkt_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
					dev->stats.rx_packets++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
		else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			skb = netdev_alloc_skb_ip_align(dev, pkt_size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
			if (likely(skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
#if RX_BUF_IDX == 3
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
				wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
#else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
				skb_copy_to_linear_data (skb, &rx_ring[ring_offset + 4],
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
						pkt_size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
				skb_put (skb, pkt_size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
				skb->protocol = eth_type_trans (skb, dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
				u64_stats_update_begin(&tp->rx_stats.syncp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
				tp->rx_stats.packets++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
				tp->rx_stats.bytes += pkt_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
				u64_stats_update_end(&tp->rx_stats.syncp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
				netif_receive_skb (skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
				dev->stats.rx_dropped++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
		received++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
		RTL_W16 (RxBufPtr, (u16) (cur_rx - 16));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
		rtl8139_isr_ack(tp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	if (unlikely(!received || rx_size == 0xfff0))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
		rtl8139_isr_ack(tp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	pr_debug("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
		 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
		 RTL_R16 (RxBufAddr),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	tp->cur_rx = cur_rx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	/*
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	 * The receive buffer should be mostly empty.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	 * Tell NAPI to reenable the Rx irq.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	if (tp->fifo_copy_timeout)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
		received = budget;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
out:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	return received;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
static void rtl8139_weird_interrupt (struct net_device *dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
				     struct rtl8139_private *tp,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
				     void __iomem *ioaddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
				     int status, int link_changed)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	pr_debug("%s: Abnormal interrupt, status %8.8x.\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
		 dev->name, status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	assert (dev != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	assert (tp != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	assert (ioaddr != NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	/* Update the error count. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	RTL_W32 (RxMissed, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	if ((status & RxUnderrun) && link_changed &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
	    (tp->drv_flags & HAS_LNK_CHNG)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
		rtl_check_media(dev, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
		status &= ~RxUnderrun;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	if (status & (RxUnderrun | RxErr))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
		dev->stats.rx_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	if (status & PCSTimeout)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
		dev->stats.rx_length_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	if (status & RxUnderrun)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
		dev->stats.rx_fifo_errors++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	if (status & PCIErr) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
		u16 pci_cmd_status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
		pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
		pr_err("%s: PCI Bus error %4.4x.\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
			dev->name, pci_cmd_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
static int rtl8139_poll(struct napi_struct *napi, int budget)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	struct rtl8139_private *tp = container_of(napi, struct rtl8139_private, napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
	struct net_device *dev = tp->dev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	int work_done;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	spin_lock(&tp->rx_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	work_done = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	if (likely(RTL_R16(IntrStatus) & RxAckBits))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
		work_done += rtl8139_rx(dev, tp, budget);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	if (work_done < budget) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
		unsigned long flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
		/*
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
		 * Order is important since data can get interrupted
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		 * again when we think we are done.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
		spin_lock_irqsave(&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
		__napi_complete(napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		RTL_W16_F(IntrMask, rtl8139_intr_mask);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
		spin_unlock_irqrestore(&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
	spin_unlock(&tp->rx_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	return work_done;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
void ec_poll(struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
	rtl8139_interrupt(0, dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
/* The interrupt handler does all of the Rx thread work and cleans up
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
   after the Tx thread. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	struct net_device *dev = (struct net_device *) dev_instance;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	u16 status, ackstat;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	int link_changed = 0; /* avoid bogus "uninit" warning */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	int handled = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	if (tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
		status = RTL_R16 (IntrStatus);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
		spin_lock (&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
		status = RTL_R16 (IntrStatus);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
		/* shared irq? */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
		if (unlikely((status & rtl8139_intr_mask) == 0))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
			goto out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	handled = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	/* h/w no longer present (hotplug?) or major error, bail */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	if (unlikely(status == 0xFFFF))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
		goto out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
		/* close possible race's with dev_close */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		if (unlikely(!netif_running(dev))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
			RTL_W16 (IntrMask, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
			goto out;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	/* Acknowledge all of the current interrupt sources ASAP, but
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	   an first get an additional status bit from CSCR. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	if (unlikely(status & RxUnderrun))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	ackstat = status & ~(RxAckBits | TxErr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	if (ackstat)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
		RTL_W16 (IntrStatus, ackstat);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	/* Receive packets are processed by poll routine.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
	   If not running start it now. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
	if (status & RxAckBits){
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		if (tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
			/* EtherCAT device: Just receive all frames */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
			rtl8139_rx(dev, tp, 100); // FIXME
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
			/* Mark for polling */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
			if (napi_schedule_prep(&tp->napi)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
				RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
				__napi_schedule(&tp->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	/* Check uncommon events with one test. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
	if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
		rtl8139_weird_interrupt (dev, tp, ioaddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
					 status, link_changed);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	if (status & (TxOK | TxErr)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
		rtl8139_tx_interrupt (dev, tp, ioaddr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
		if (status & TxErr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
			RTL_W16 (IntrStatus, TxErr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
out:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
		spin_unlock (&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	pr_debug("%s: exiting interrupt, intr_status=%#4.4x.\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
		 dev->name, RTL_R16 (IntrStatus));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	return IRQ_RETVAL(handled);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
#ifdef CONFIG_NET_POLL_CONTROLLER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
/*
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
 * Polling receive - used by netconsole and other diagnostic tools
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
 * to allow network i/o with interrupts disabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
static void rtl8139_poll_controller(struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	const int irq = tp->pci_dev->irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
	disable_irq(irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
	rtl8139_interrupt(irq, dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
	enable_irq(irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
static int rtl8139_set_mac_address(struct net_device *dev, void *p)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	struct sockaddr *addr = p;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
	if (!is_valid_ether_addr(addr->sa_data))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
		return -EADDRNOTAVAIL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
	spin_lock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	RTL_W8_F(Cfg9346, Cfg9346_Unlock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	RTL_W32_F(MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
	RTL_W32_F(MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	RTL_W8_F(Cfg9346, Cfg9346_Lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	spin_unlock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
static int rtl8139_close (struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
	unsigned long flags = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
		netif_stop_queue(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
		napi_disable(&tp->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
		netif_dbg(tp, ifdown, dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
				"Shutting down ethercard, status was 0x%04x\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
				RTL_R16(IntrStatus));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		spin_lock_irqsave (&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	/* Stop the chip's Tx and Rx DMA processes. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	RTL_W8 (ChipCmd, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	/* Disable interrupts by clearing the interrupt mask. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	RTL_W16 (IntrMask, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	/* Update the error counts. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	RTL_W32 (RxMissed, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	if (!tp->ecdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
		spin_unlock_irqrestore (&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
		free_irq(tp->pci_dev->irq, dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
	rtl8139_tx_clear (tp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	dma_free_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
			  tp->rx_ring, tp->rx_ring_dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	dma_free_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
			  tp->tx_bufs, tp->tx_bufs_dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	tp->rx_ring = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	tp->tx_bufs = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	/* Green! Put the chip in low-power mode. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	RTL_W8 (Cfg9346, Cfg9346_Unlock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
/* Get the ethtool Wake-on-LAN settings.  Assumes that wol points to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
   kernel memory, *wol has been initialized as {ETHTOOL_GWOL}, and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
   other threads or interrupts aren't messing with the 8139.  */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
	spin_lock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
	if (rtl_chip_info[tp->chipset].flags & HasLWake) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
		u8 cfg3 = RTL_R8 (Config3);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
		u8 cfg5 = RTL_R8 (Config5);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
		wol->supported = WAKE_PHY | WAKE_MAGIC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
			| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
		wol->wolopts = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
		if (cfg3 & Cfg3_LinkUp)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
			wol->wolopts |= WAKE_PHY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
		if (cfg3 & Cfg3_Magic)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
			wol->wolopts |= WAKE_MAGIC;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
		/* (KON)FIXME: See how netdev_set_wol() handles the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
		   following constants.  */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
		if (cfg5 & Cfg5_UWF)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
			wol->wolopts |= WAKE_UCAST;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
		if (cfg5 & Cfg5_MWF)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
			wol->wolopts |= WAKE_MCAST;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
		if (cfg5 & Cfg5_BWF)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
			wol->wolopts |= WAKE_BCAST;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
	spin_unlock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
/* Set the ethtool Wake-on-LAN settings.  Return 0 or -errno.  Assumes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
   that wol points to kernel memory and other threads or interrupts
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
   aren't messing with the 8139.  */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	u32 support;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	u8 cfg3, cfg5;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	support = ((rtl_chip_info[tp->chipset].flags & HasLWake)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		   ? (WAKE_PHY | WAKE_MAGIC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
		      | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		   : 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	if (wol->wolopts & ~support)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	spin_lock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
	cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
	if (wol->wolopts & WAKE_PHY)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		cfg3 |= Cfg3_LinkUp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	if (wol->wolopts & WAKE_MAGIC)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
		cfg3 |= Cfg3_Magic;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	RTL_W8 (Cfg9346, Cfg9346_Unlock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	RTL_W8 (Config3, cfg3);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	RTL_W8 (Cfg9346, Cfg9346_Lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
	cfg5 = RTL_R8 (Config5) & ~(Cfg5_UWF | Cfg5_MWF | Cfg5_BWF);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	/* (KON)FIXME: These are untested.  We may have to set the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	   CRC0, Wakeup0 and LSBCRC0 registers too, but I have no
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	   documentation.  */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	if (wol->wolopts & WAKE_UCAST)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
		cfg5 |= Cfg5_UWF;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	if (wol->wolopts & WAKE_MCAST)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		cfg5 |= Cfg5_MWF;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
	if (wol->wolopts & WAKE_BCAST)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		cfg5 |= Cfg5_BWF;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
	RTL_W8 (Config5, cfg5);	/* need not unlock via Cfg9346 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	spin_unlock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
	strlcpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
	info->regdump_len = tp->regs_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	spin_lock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	mii_ethtool_gset(&tp->mii, cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
	spin_unlock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	int rc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
	spin_lock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	rc = mii_ethtool_sset(&tp->mii, cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
	spin_unlock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	return rc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
static int rtl8139_nway_reset(struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	return mii_nway_restart(&tp->mii);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
static u32 rtl8139_get_link(struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
	return mii_link_ok(&tp->mii);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
static u32 rtl8139_get_msglevel(struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	return tp->msg_enable;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	tp->msg_enable = datum;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
static int rtl8139_get_regs_len(struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	struct rtl8139_private *tp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	/* TODO: we are too slack to do reg dumping for pio, for now */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
	if (use_io)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
	tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
	return tp->regs_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
	struct rtl8139_private *tp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	/* TODO: we are too slack to do reg dumping for pio, for now */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
	if (use_io)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	regs->version = RTL_REGS_VER;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
	spin_lock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
	memcpy_fromio(regbuf, tp->mmio_addr, regs->len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	spin_unlock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
static int rtl8139_get_sset_count(struct net_device *dev, int sset)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	switch (sset) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
	case ETH_SS_STATS:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
		return RTL_NUM_STATS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		return -EOPNOTSUPP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	data[0] = tp->xstats.early_rx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	data[1] = tp->xstats.tx_buf_mapped;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
	data[2] = tp->xstats.tx_timeouts;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
	data[3] = tp->xstats.rx_lost_in_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
static const struct ethtool_ops rtl8139_ethtool_ops = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	.get_drvinfo		= rtl8139_get_drvinfo,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
	.get_settings		= rtl8139_get_settings,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	.set_settings		= rtl8139_set_settings,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	.get_regs_len		= rtl8139_get_regs_len,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	.get_regs		= rtl8139_get_regs,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	.nway_reset		= rtl8139_nway_reset,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	.get_link		= rtl8139_get_link,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	.get_msglevel		= rtl8139_get_msglevel,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	.set_msglevel		= rtl8139_set_msglevel,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	.get_wol		= rtl8139_get_wol,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
	.set_wol		= rtl8139_set_wol,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
	.get_strings		= rtl8139_get_strings,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	.get_sset_count		= rtl8139_get_sset_count,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
	.get_ethtool_stats	= rtl8139_get_ethtool_stats,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
	int rc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	if (tp->ecdev || !netif_running(dev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
		return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	spin_lock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	rc = generic_mii_ioctl(&tp->mii, if_mii(rq), cmd, NULL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	spin_unlock_irq(&tp->lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	return rc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
static struct rtnl_link_stats64 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
rtl8139_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	unsigned long flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	unsigned int start;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
	if (tp->ecdev || netif_running(dev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
		spin_lock_irqsave (&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
		dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
		RTL_W32 (RxMissed, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
		spin_unlock_irqrestore (&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	netdev_stats_to_stats64(stats, &dev->stats);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
	do {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
		start = u64_stats_fetch_begin_bh(&tp->rx_stats.syncp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
		stats->rx_packets = tp->rx_stats.packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
		stats->rx_bytes = tp->rx_stats.bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	} while (u64_stats_fetch_retry_bh(&tp->rx_stats.syncp, start));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	do {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		start = u64_stats_fetch_begin_bh(&tp->tx_stats.syncp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
		stats->tx_packets = tp->tx_stats.packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		stats->tx_bytes = tp->tx_stats.bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	} while (u64_stats_fetch_retry_bh(&tp->tx_stats.syncp, start));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	return stats;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
/* Set or clear the multicast filter for this adaptor.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
   This routine is not state sensitive and need not be SMP locked. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
static void __set_rx_mode (struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
	u32 mc_filter[2];	/* Multicast hash filter */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
	int rx_mode;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
	u32 tmp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
	netdev_dbg(dev, "rtl8139_set_rx_mode(%04x) done -- Rx config %08x\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
		   dev->flags, RTL_R32(RxConfig));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
	/* Note: do not reorder, GCC is clever about common statements. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	if (dev->flags & IFF_PROMISC) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
		rx_mode =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		    AcceptAllPhys;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
		mc_filter[1] = mc_filter[0] = 0xffffffff;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
		   (dev->flags & IFF_ALLMULTI)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
		/* Too many to filter perfectly -- accept all multicasts. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
		mc_filter[1] = mc_filter[0] = 0xffffffff;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
		struct netdev_hw_addr *ha;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
		rx_mode = AcceptBroadcast | AcceptMyPhys;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
		mc_filter[1] = mc_filter[0] = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
		netdev_for_each_mc_addr(ha, dev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
			int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
			rx_mode |= AcceptMulticast;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
	if (dev->features & NETIF_F_RXALL)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
		rx_mode |= (AcceptErr | AcceptRunt);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	/* We can safely update without stopping the chip. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	tmp = rtl8139_rx_config | rx_mode;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
	if (tp->rx_config != tmp) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
		RTL_W32_F (RxConfig, tmp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
		tp->rx_config = tmp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	RTL_W32_F (MAR0 + 0, mc_filter[0]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	RTL_W32_F (MAR0 + 4, mc_filter[1]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
static void rtl8139_set_rx_mode (struct net_device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	unsigned long flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
	spin_lock_irqsave (&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
	__set_rx_mode(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	spin_unlock_irqrestore (&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
	struct net_device *dev = pci_get_drvdata (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
	void __iomem *ioaddr = tp->mmio_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
	unsigned long flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	pci_save_state (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
	if (tp->ecdev || !netif_running (dev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
	netif_device_detach (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	spin_lock_irqsave (&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	/* Disable interrupts, stop Tx and Rx. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
	RTL_W16 (IntrMask, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	RTL_W8 (ChipCmd, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
	/* Update the error counts. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	RTL_W32 (RxMissed, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	spin_unlock_irqrestore (&tp->lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	pci_set_power_state (pdev, PCI_D3hot);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
static int rtl8139_resume (struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
	struct net_device *dev = pci_get_drvdata (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
	struct rtl8139_private *tp = netdev_priv(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	pci_restore_state (pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	if (tp->ecdev || !netif_running (dev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
	pci_set_power_state (pdev, PCI_D0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	rtl8139_init_ring (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	rtl8139_hw_start (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
	netif_device_attach (dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
#endif /* CONFIG_PM */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
static struct pci_driver rtl8139_pci_driver = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
	.name		= DRV_NAME,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
	.id_table	= rtl8139_pci_tbl,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
	.probe		= rtl8139_init_one,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
	.remove		= rtl8139_remove_one,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	.suspend	= rtl8139_suspend,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	.resume		= rtl8139_resume,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
#endif /* CONFIG_PM */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
static int __init rtl8139_init_module (void)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
	/* when we're a module, we always print a version message,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
	 * even if no 8139 board is found.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
#ifdef MODULE
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
	pr_info(RTL8139_DRIVER_NAME "\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	return pci_register_driver(&rtl8139_pci_driver);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
static void __exit rtl8139_cleanup_module (void)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
	pci_unregister_driver (&rtl8139_pci_driver);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
module_init(rtl8139_init_module);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
module_exit(rtl8139_cleanup_module);