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