devices/r8169-2.6.24-orig.c
author Gavin Lambert <gavinl@compacsort.com>
Tue, 14 Apr 2015 09:33:24 -0400
changeset 2618 3affe9cd0b66
parent 1353 22b1de4c74e4
permissions -rw-r--r--
Ignore NXIO error otherwise this causes spam if network is empty or refclk not
selected yet, and syncing refclk time to master.
1353
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
 * r8169.c: RealTek 8169/8168/8101 ethernet driver.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
 *
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
 * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
 * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
 * Copyright (c) a lot of people too. Please respect their work.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
 *
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
 * See MAINTAINERS file for support contact information.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
#include <linux/module.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
#include <linux/moduleparam.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
#include <linux/pci.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
#include <linux/netdevice.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
#include <linux/etherdevice.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
#include <linux/delay.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
#include <linux/ethtool.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
#include <linux/mii.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
#include <linux/if_vlan.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
#include <linux/crc32.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
#include <linux/in.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
#include <linux/ip.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
#include <linux/tcp.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
#include <linux/init.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
#include <linux/dma-mapping.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
#include <asm/system.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
#include <asm/io.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include <asm/irq.h>
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#define NAPI_SUFFIX	"-NAPI"
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#define NAPI_SUFFIX	""
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#define RTL8169_VERSION "2.2LK" NAPI_SUFFIX
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#define MODULENAME "r8169"
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#define PFX MODULENAME ": "
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#ifdef RTL8169_DEBUG
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#define assert(expr) \
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
	if (!(expr)) {					\
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
		printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
		#expr,__FILE__,__FUNCTION__,__LINE__);		\
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#define dprintk(fmt, args...) \
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	do { printk(KERN_DEBUG PFX fmt, ## args); } while (0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
#else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
#define assert(expr) do {} while (0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
#define dprintk(fmt, args...)	do {} while (0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
#endif /* RTL8169_DEBUG */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
#define R8169_MSG_DEFAULT \
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	(NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
#define TX_BUFFS_AVAIL(tp) \
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
#define rtl8169_rx_skb			netif_receive_skb
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
#define rtl8169_rx_hwaccel_skb		vlan_hwaccel_receive_skb
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
#define rtl8169_rx_quota(count, quota)	min(count, quota)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
#else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
#define rtl8169_rx_skb			netif_rx
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
#define rtl8169_rx_hwaccel_skb		vlan_hwaccel_rx
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
#define rtl8169_rx_quota(count, quota)	count
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
static const int max_interrupt_work = 20;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
   The RTL chips use a 64 element hash table based on the Ethernet CRC. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
static const int multicast_filter_limit = 32;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
/* MAC address length */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
#define MAC_ADDR_LEN	6
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
#define RX_FIFO_THRESH	7	/* 7 means NO threshold, Rx buffer level before first PCI xfer. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
#define RX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
#define EarlyTxThld	0x3F	/* 0x3F means NO early transmit */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
#define RxPacketMaxSize	0x3FE8	/* 16K - 1 - ETH_HLEN - VLAN - CRC... */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
#define SafeMtu		0x1c20	/* ... actually life sucks beyond ~7k */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
#define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
#define R8169_REGS_SIZE		256
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
#define R8169_NAPI_WEIGHT	64
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
#define NUM_TX_DESC	64	/* Number of Tx descriptor registers */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
#define NUM_RX_DESC	256	/* Number of Rx descriptor registers */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
#define RX_BUF_SIZE	1536	/* Rx Buffer size */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
#define R8169_TX_RING_BYTES	(NUM_TX_DESC * sizeof(struct TxDesc))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
#define R8169_RX_RING_BYTES	(NUM_RX_DESC * sizeof(struct RxDesc))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
#define RTL8169_TX_TIMEOUT	(6*HZ)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
#define RTL8169_PHY_TIMEOUT	(10*HZ)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
/* write/read MMIO register */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
#define RTL_W8(reg, val8)	writeb ((val8), ioaddr + (reg))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
#define RTL_W16(reg, val16)	writew ((val16), ioaddr + (reg))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
#define RTL_W32(reg, val32)	writel ((val32), ioaddr + (reg))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
#define RTL_R8(reg)		readb (ioaddr + (reg))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
#define RTL_R16(reg)		readw (ioaddr + (reg))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
#define RTL_R32(reg)		((unsigned long) readl (ioaddr + (reg)))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
enum mac_version {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	RTL_GIGA_MAC_VER_01 = 0x01, // 8169
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
	RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 ?
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	RTL_GIGA_MAC_VER_15 = 0x0f, // 8101 ?
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	RTL_GIGA_MAC_VER_16 = 0x11, // 8101Ec
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
	RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
	RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	RTL_GIGA_MAC_VER_19 = 0x13, // 8168C
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	RTL_GIGA_MAC_VER_20 = 0x14  // 8168C
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
#define _R(NAME,MAC,MASK) \
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	{ .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static const struct {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	const char *name;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
	u8 mac_version;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
	u32 RxConfigMask;	/* Clears the bits supported by this chip */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
} rtl_chip_info[] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
	_R("RTL8169",		RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
	_R("RTL8169s",		RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
	_R("RTL8110s",		RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
	_R("RTL8169sb/8110sb",	RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	_R("RTL8101e",		RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	_R("RTL8100e",		RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
	_R("RTL8100e",		RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
	_R("RTL8101e",		RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
	_R("RTL8168cp/8111cp",	RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
	_R("RTL8168c/8111c",	RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
	_R("RTL8168c/8111c",	RTL_GIGA_MAC_VER_20, 0xff7e1880)  // PCI-E
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
#undef _R
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
enum cfg_version {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
	RTL_CFG_0 = 0x00,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
	RTL_CFG_1,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
	RTL_CFG_2
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
static void rtl_hw_start_8169(struct net_device *);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static void rtl_hw_start_8168(struct net_device *);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static void rtl_hw_start_8101(struct net_device *);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static struct pci_device_id rtl8169_pci_tbl[] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), 0, 0, RTL_CFG_0 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8136), 0, 0, RTL_CFG_2 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8167), 0, 0, RTL_CFG_0 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, RTL_CFG_1 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), 0, 0, RTL_CFG_0 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), 0, 0, RTL_CFG_0 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
	{ PCI_DEVICE(PCI_VENDOR_ID_AT,		0xc107), 0, 0, RTL_CFG_0 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
	{ PCI_DEVICE(0x16ec,			0x0116), 0, 0, RTL_CFG_0 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
	{ PCI_VENDOR_ID_LINKSYS,		0x1032,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
		PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
	{ 0x0001,				0x8168,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
		PCI_ANY_ID, 0x2410, 0, 0, RTL_CFG_2 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
	{0,},
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
static int rx_copybreak = 200;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
static int use_dac;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
static struct {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
	u32 msg_enable;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
} debug = { -1 };
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
enum rtl_registers {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	MAC0		= 0,	/* Ethernet hardware address. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	MAC4		= 4,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	MAR0		= 8,	/* Multicast filter. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	CounterAddrLow		= 0x10,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	CounterAddrHigh		= 0x14,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	TxDescStartAddrLow	= 0x20,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	TxDescStartAddrHigh	= 0x24,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	TxHDescStartAddrLow	= 0x28,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	TxHDescStartAddrHigh	= 0x2c,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	FLASH		= 0x30,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	ERSR		= 0x36,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	ChipCmd		= 0x37,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	TxPoll		= 0x38,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	IntrMask	= 0x3c,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	IntrStatus	= 0x3e,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	TxConfig	= 0x40,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	RxConfig	= 0x44,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	RxMissed	= 0x4c,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	Cfg9346		= 0x50,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	Config0		= 0x51,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	Config1		= 0x52,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	Config2		= 0x53,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	Config3		= 0x54,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	Config4		= 0x55,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	Config5		= 0x56,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	MultiIntr	= 0x5c,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	PHYAR		= 0x60,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	TBICSR		= 0x64,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	TBI_ANAR	= 0x68,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	TBI_LPAR	= 0x6a,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
	PHYstatus	= 0x6c,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	RxMaxSize	= 0xda,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
	CPlusCmd	= 0xe0,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	IntrMitigate	= 0xe2,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
	RxDescAddrLow	= 0xe4,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	RxDescAddrHigh	= 0xe8,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	EarlyTxThres	= 0xec,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	FuncEvent	= 0xf0,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	FuncEventMask	= 0xf4,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	FuncPresetState	= 0xf8,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	FuncForceEvent	= 0xfc,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
enum rtl_register_content {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	/* InterruptStatusBits */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	SYSErr		= 0x8000,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	PCSTimeout	= 0x4000,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
	SWInt		= 0x0100,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	TxDescUnavail	= 0x0080,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	RxFIFOOver	= 0x0040,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	LinkChg		= 0x0020,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	RxOverflow	= 0x0010,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
	TxErr		= 0x0008,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	TxOK		= 0x0004,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	RxErr		= 0x0002,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	RxOK		= 0x0001,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	/* RxStatusDesc */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
	RxFOVF	= (1 << 23),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	RxRWT	= (1 << 22),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	RxRES	= (1 << 21),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	RxRUNT	= (1 << 20),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	RxCRC	= (1 << 19),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	/* ChipCmdBits */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	CmdReset	= 0x10,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	CmdRxEnb	= 0x08,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	CmdTxEnb	= 0x04,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	RxBufEmpty	= 0x01,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	/* TXPoll register p.5 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	HPQ		= 0x80,		/* Poll cmd on the high prio queue */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	NPQ		= 0x40,		/* Poll cmd on the low prio queue */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	FSWInt		= 0x01,		/* Forced software interrupt */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	/* Cfg9346Bits */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	Cfg9346_Lock	= 0x00,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	Cfg9346_Unlock	= 0xc0,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	/* rx_mode_bits */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	AcceptErr	= 0x20,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	AcceptRunt	= 0x10,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	AcceptBroadcast	= 0x08,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	AcceptMulticast	= 0x04,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	AcceptMyPhys	= 0x02,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	AcceptAllPhys	= 0x01,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	/* RxConfigBits */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	RxCfgFIFOShift	= 13,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	RxCfgDMAShift	=  8,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	/* TxConfigBits */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	TxInterFrameGapShift = 24,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	TxDMAShift = 8,	/* DMA burst value (0-7) is shift this many bits */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	/* Config1 register p.24 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	MSIEnable	= (1 << 5),	/* Enable Message Signaled Interrupt */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	PMEnable	= (1 << 0),	/* Power Management Enable */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	/* Config2 register p. 25 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	PCI_Clock_66MHz = 0x01,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	PCI_Clock_33MHz = 0x00,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	/* Config3 register p.25 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	MagicPacket	= (1 << 5),	/* Wake up when receives a Magic Packet */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	LinkUp		= (1 << 4),	/* Wake up when the cable connection is re-established */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	/* Config5 register p.27 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	BWF		= (1 << 6),	/* Accept Broadcast wakeup frame */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	MWF		= (1 << 5),	/* Accept Multicast wakeup frame */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	UWF		= (1 << 4),	/* Accept Unicast wakeup frame */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	LanWake		= (1 << 1),	/* LanWake enable/disable */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	PMEStatus	= (1 << 0),	/* PME status can be reset by PCI RST# */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	/* TBICSR p.28 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	TBIReset	= 0x80000000,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	TBILoopback	= 0x40000000,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	TBINwEnable	= 0x20000000,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	TBINwRestart	= 0x10000000,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	TBILinkOk	= 0x02000000,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
	TBINwComplete	= 0x01000000,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	/* CPlusCmd p.31 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	PktCntrDisable	= (1 << 7),	// 8168
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	RxVlan		= (1 << 6),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	RxChkSum	= (1 << 5),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	PCIDAC		= (1 << 4),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	PCIMulRW	= (1 << 3),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	INTT_0		= 0x0000,	// 8168
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	INTT_1		= 0x0001,	// 8168
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	INTT_2		= 0x0002,	// 8168
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	INTT_3		= 0x0003,	// 8168
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	/* rtl8169_PHYstatus */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	TBI_Enable	= 0x80,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	TxFlowCtrl	= 0x40,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	RxFlowCtrl	= 0x20,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	_1000bpsF	= 0x10,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	_100bps		= 0x08,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	_10bps		= 0x04,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	LinkStatus	= 0x02,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	FullDup		= 0x01,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	/* _TBICSRBit */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	TBILinkOK	= 0x02000000,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
	/* DumpCounterCommand */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	CounterDump	= 0x8,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
enum desc_status_bit {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	DescOwn		= (1 << 31), /* Descriptor is owned by NIC */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	RingEnd		= (1 << 30), /* End of descriptor ring */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	FirstFrag	= (1 << 29), /* First segment of a packet */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	LastFrag	= (1 << 28), /* Final segment of a packet */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	/* Tx private */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
	LargeSend	= (1 << 27), /* TCP Large Send Offload (TSO) */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	MSSShift	= 16,        /* MSS value position */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
	MSSMask		= 0xfff,     /* MSS value + LargeSend bit: 12 bits */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	IPCS		= (1 << 18), /* Calculate IP checksum */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	UDPCS		= (1 << 17), /* Calculate UDP/IP checksum */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	TCPCS		= (1 << 16), /* Calculate TCP/IP checksum */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	TxVlanTag	= (1 << 17), /* Add VLAN tag */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	/* Rx private */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
	PID1		= (1 << 18), /* Protocol ID bit 1/2 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	PID0		= (1 << 17), /* Protocol ID bit 2/2 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
#define RxProtoUDP	(PID1)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
#define RxProtoTCP	(PID0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
#define RxProtoIP	(PID1 | PID0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
#define RxProtoMask	RxProtoIP
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	IPFail		= (1 << 16), /* IP checksum failed */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
	UDPFail		= (1 << 15), /* UDP/IP checksum failed */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	TCPFail		= (1 << 14), /* TCP/IP checksum failed */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	RxVlanTag	= (1 << 16), /* VLAN tag available */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
#define RsvdMask	0x3fffc000
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
struct TxDesc {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	__le32 opts1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	__le32 opts2;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	__le64 addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
struct RxDesc {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
	__le32 opts1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	__le32 opts2;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	__le64 addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
struct ring_info {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
	struct sk_buff	*skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	u32		len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
	u8		__pad[sizeof(void *) - sizeof(u32)];
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
enum features {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	RTL_FEATURE_WOL	= (1 << 0),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	RTL_FEATURE_MSI	= (1 << 1),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
struct rtl8169_private {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	void __iomem *mmio_addr;	/* memory map physical address */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	struct pci_dev *pci_dev;	/* Index of PCI device */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	struct net_device *dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	struct napi_struct napi;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	spinlock_t lock;		/* spin lock flag */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	u32 msg_enable;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	int chipset;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
	int mac_version;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
	u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	u32 dirty_rx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	u32 dirty_tx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	struct TxDesc *TxDescArray;	/* 256-aligned Tx descriptor ring */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	struct RxDesc *RxDescArray;	/* 256-aligned Rx descriptor ring */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	dma_addr_t TxPhyAddr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	dma_addr_t RxPhyAddr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	struct sk_buff *Rx_skbuff[NUM_RX_DESC];	/* Rx data buffers */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	struct ring_info tx_skb[NUM_TX_DESC];	/* Tx data buffers */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	unsigned align;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	unsigned rx_buf_sz;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	struct timer_list timer;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	u16 cp_cmd;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	u16 intr_event;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	u16 napi_event;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	u16 intr_mask;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	int phy_auto_nego_reg;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	int phy_1000_ctrl_reg;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
#ifdef CONFIG_R8169_VLAN
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	struct vlan_group *vlgrp;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
	void (*get_settings)(struct net_device *, struct ethtool_cmd *);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	void (*phy_reset_enable)(void __iomem *);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	void (*hw_start)(struct net_device *);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	unsigned int (*phy_reset_pending)(void __iomem *);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	unsigned int (*link_ok)(void __iomem *);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	struct delayed_work task;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	unsigned features;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
module_param(rx_copybreak, int, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
module_param(use_dac, int, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
module_param_named(debug, debug.msg_enable, int, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
MODULE_LICENSE("GPL");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
MODULE_VERSION(RTL8169_VERSION);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
static int rtl8169_open(struct net_device *dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
static int rtl8169_init_ring(struct net_device *dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
static void rtl_hw_start(struct net_device *dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
static int rtl8169_close(struct net_device *dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
static void rtl_set_rx_mode(struct net_device *dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
static void rtl8169_tx_timeout(struct net_device *dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
				void __iomem *, u32 budget);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
static void rtl8169_down(struct net_device *dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
static void rtl8169_rx_clear(struct rtl8169_private *tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
static int rtl8169_poll(struct napi_struct *napi, int budget);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
static const unsigned int rtl8169_rx_config =
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	for (i = 20; i > 0; i--) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		 * Check if the RTL8169 has completed writing to the specified
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		 * MII register.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		if (!(RTL_R32(PHYAR) & 0x80000000))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		udelay(25);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
static int mdio_read(void __iomem *ioaddr, int reg_addr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	int i, value = -1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	for (i = 20; i > 0; i--) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
		/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		 * Check if the RTL8169 has completed retrieving data from
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		 * the specified MII register.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		if (RTL_R32(PHYAR) & 0x80000000) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
			value = RTL_R32(PHYAR) & 0xffff;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
		udelay(25);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	return value;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	RTL_W16(IntrMask, 0x0000);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	RTL_W16(IntrStatus, 0xffff);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
static void rtl8169_asic_down(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	RTL_W8(ChipCmd, 0x00);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	rtl8169_irq_mask_and_ack(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	RTL_R16(CPlusCmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
static unsigned int rtl8169_tbi_reset_pending(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	return RTL_R32(TBICSR) & TBIReset;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
static unsigned int rtl8169_xmii_reset_pending(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	return mdio_read(ioaddr, MII_BMCR) & BMCR_RESET;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	return RTL_R32(TBICSR) & TBILinkOk;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
static unsigned int rtl8169_xmii_link_ok(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	return RTL_R8(PHYstatus) & LinkStatus;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
static void rtl8169_tbi_reset_enable(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	unsigned int val;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	mdio_write(ioaddr, MII_BMCR, val & 0xffff);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
static void rtl8169_check_link_status(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
				      struct rtl8169_private *tp,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
				      void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	unsigned long flags;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	spin_lock_irqsave(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	if (tp->link_ok(ioaddr)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
		netif_carrier_on(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
		if (netif_msg_ifup(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
			printk(KERN_INFO PFX "%s: link up\n", dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
		if (netif_msg_ifdown(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
			printk(KERN_INFO PFX "%s: link down\n", dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		netif_carrier_off(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	spin_unlock_irqrestore(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	u8 options;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	wol->wolopts = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	wol->supported = WAKE_ANY;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	spin_lock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	options = RTL_R8(Config1);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	if (!(options & PMEnable))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		goto out_unlock;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	options = RTL_R8(Config3);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	if (options & LinkUp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
		wol->wolopts |= WAKE_PHY;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	if (options & MagicPacket)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
		wol->wolopts |= WAKE_MAGIC;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	options = RTL_R8(Config5);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	if (options & UWF)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
		wol->wolopts |= WAKE_UCAST;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	if (options & BWF)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		wol->wolopts |= WAKE_BCAST;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	if (options & MWF)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		wol->wolopts |= WAKE_MCAST;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
out_unlock:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	spin_unlock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	unsigned int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	static struct {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		u32 opt;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		u16 reg;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
		u8  mask;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
	} cfg[] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
		{ WAKE_ANY,   Config1, PMEnable },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
		{ WAKE_PHY,   Config3, LinkUp },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
		{ WAKE_MAGIC, Config3, MagicPacket },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
		{ WAKE_UCAST, Config5, UWF },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
		{ WAKE_BCAST, Config5, BWF },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		{ WAKE_MCAST, Config5, MWF },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		{ WAKE_ANY,   Config5, LanWake }
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	spin_lock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	RTL_W8(Cfg9346, Cfg9346_Unlock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	for (i = 0; i < ARRAY_SIZE(cfg); i++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		if (wol->wolopts & cfg[i].opt)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
			options |= cfg[i].mask;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		RTL_W8(cfg[i].reg, options);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	RTL_W8(Cfg9346, Cfg9346_Lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	if (wol->wolopts)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		tp->features |= RTL_FEATURE_WOL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
		tp->features &= ~RTL_FEATURE_WOL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	spin_unlock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
static void rtl8169_get_drvinfo(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
				struct ethtool_drvinfo *info)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	strcpy(info->driver, MODULENAME);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	strcpy(info->version, RTL8169_VERSION);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	strcpy(info->bus_info, pci_name(tp->pci_dev));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
static int rtl8169_get_regs_len(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	return R8169_REGS_SIZE;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
static int rtl8169_set_speed_tbi(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
				 u8 autoneg, u16 speed, u8 duplex)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
	int ret = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	u32 reg;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	reg = RTL_R32(TBICSR);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	if ((autoneg == AUTONEG_DISABLE) && (speed == SPEED_1000) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	    (duplex == DUPLEX_FULL)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		RTL_W32(TBICSR, reg & ~(TBINwEnable | TBINwRestart));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	} else if (autoneg == AUTONEG_ENABLE)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
		RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
		if (netif_msg_link(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
			printk(KERN_WARNING "%s: "
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
			       "incorrect speed setting refused in TBI mode\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
			       dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
		ret = -EOPNOTSUPP;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	return ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
static int rtl8169_set_speed_xmii(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
				  u8 autoneg, u16 speed, u8 duplex)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
	int auto_nego, giga_ctrl;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
		       ADVERTISE_100HALF | ADVERTISE_100FULL);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
	giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	if (autoneg == AUTONEG_ENABLE) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
		auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
			      ADVERTISE_100HALF | ADVERTISE_100FULL);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
		giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
		if (speed == SPEED_10)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
			auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
		else if (speed == SPEED_100)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
			auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
		else if (speed == SPEED_1000)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
			giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
		if (duplex == DUPLEX_HALF)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
			auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
		if (duplex == DUPLEX_FULL)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
			auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
		/* This tweak comes straight from Realtek's driver. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
		if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
		    ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
		     (tp->mac_version == RTL_GIGA_MAC_VER_16))) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
			auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	/* The 8100e/8101e do Fast Ethernet only. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	    (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	    (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
		    netif_msg_link(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
			printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
			       dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
		giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	if ((tp->mac_version == RTL_GIGA_MAC_VER_12) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	    (tp->mac_version == RTL_GIGA_MAC_VER_17)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		/* Vendor specific (0x1f) and reserved (0x0e) MII registers. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
		mdio_write(ioaddr, 0x1f, 0x0000);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		mdio_write(ioaddr, 0x0e, 0x0000);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	tp->phy_auto_nego_reg = auto_nego;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	tp->phy_1000_ctrl_reg = giga_ctrl;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
static int rtl8169_set_speed(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
			     u8 autoneg, u16 speed, u8 duplex)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	int ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	ret = tp->set_speed(dev, autoneg, speed, duplex);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	if (netif_running(dev) && (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
		mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	return ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	unsigned long flags;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	int ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	spin_lock_irqsave(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	ret = rtl8169_set_speed(dev, cmd->autoneg, cmd->speed, cmd->duplex);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	spin_unlock_irqrestore(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	return ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
static u32 rtl8169_get_rx_csum(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	return tp->cp_cmd & RxChkSum;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
static int rtl8169_set_rx_csum(struct net_device *dev, u32 data)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	unsigned long flags;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	spin_lock_irqsave(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	if (data)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
		tp->cp_cmd |= RxChkSum;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
		tp->cp_cmd &= ~RxChkSum;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	RTL_W16(CPlusCmd, tp->cp_cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	RTL_R16(CPlusCmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	spin_unlock_irqrestore(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
#ifdef CONFIG_R8169_VLAN
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
				      struct sk_buff *skb)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	return (tp->vlgrp && vlan_tx_tag_present(skb)) ?
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
static void rtl8169_vlan_rx_register(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
				     struct vlan_group *grp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	unsigned long flags;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	spin_lock_irqsave(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	tp->vlgrp = grp;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	if (tp->vlgrp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
		tp->cp_cmd |= RxVlan;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
		tp->cp_cmd &= ~RxVlan;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	RTL_W16(CPlusCmd, tp->cp_cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	RTL_R16(CPlusCmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	spin_unlock_irqrestore(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
			       struct sk_buff *skb)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	u32 opts2 = le32_to_cpu(desc->opts2);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	int ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	if (tp->vlgrp && (opts2 & RxVlanTag)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
		rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, swab16(opts2 & 0xffff));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
		ret = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	} else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
		ret = -1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	desc->opts2 = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	return ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
#else /* !CONFIG_R8169_VLAN */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
				      struct sk_buff *skb)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
			       struct sk_buff *skb)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	return -1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	u32 status;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	cmd->supported =
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	cmd->port = PORT_FIBRE;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	cmd->transceiver = XCVR_INTERNAL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	status = RTL_R32(TBICSR);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	cmd->advertising = (status & TBINwEnable) ?  ADVERTISED_Autoneg : 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	cmd->autoneg = !!(status & TBINwEnable);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	cmd->speed = SPEED_1000;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	cmd->duplex = DUPLEX_FULL; /* Always set */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	u8 status;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	cmd->supported = SUPPORTED_10baseT_Half |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
			 SUPPORTED_10baseT_Full |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
			 SUPPORTED_100baseT_Half |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
			 SUPPORTED_100baseT_Full |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
			 SUPPORTED_1000baseT_Full |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
			 SUPPORTED_Autoneg |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
			 SUPPORTED_TP;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	cmd->autoneg = 1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		cmd->advertising |= ADVERTISED_10baseT_Half;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
		cmd->advertising |= ADVERTISED_10baseT_Full;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
		cmd->advertising |= ADVERTISED_100baseT_Half;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
		cmd->advertising |= ADVERTISED_100baseT_Full;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
		cmd->advertising |= ADVERTISED_1000baseT_Full;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	status = RTL_R8(PHYstatus);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	if (status & _1000bpsF)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
		cmd->speed = SPEED_1000;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	else if (status & _100bps)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
		cmd->speed = SPEED_100;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	else if (status & _10bps)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
		cmd->speed = SPEED_10;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	if (status & TxFlowCtrl)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
		cmd->advertising |= ADVERTISED_Asym_Pause;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	if (status & RxFlowCtrl)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
		cmd->advertising |= ADVERTISED_Pause;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		      DUPLEX_FULL : DUPLEX_HALF;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	unsigned long flags;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	spin_lock_irqsave(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	tp->get_settings(dev, cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	spin_unlock_irqrestore(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
			     void *p)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	unsigned long flags;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	if (regs->len > R8169_REGS_SIZE)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
		regs->len = R8169_REGS_SIZE;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	spin_lock_irqsave(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	memcpy_fromio(p, tp->mmio_addr, regs->len);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	spin_unlock_irqrestore(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
static u32 rtl8169_get_msglevel(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	return tp->msg_enable;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
static void rtl8169_set_msglevel(struct net_device *dev, u32 value)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	tp->msg_enable = value;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	"tx_packets",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	"rx_packets",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	"tx_errors",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	"rx_errors",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	"rx_missed",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	"align_errors",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	"tx_single_collisions",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	"tx_multi_collisions",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	"unicast",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	"broadcast",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	"multicast",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	"tx_aborted",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	"tx_underrun",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
struct rtl8169_counters {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	__le64	tx_packets;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	__le64	rx_packets;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	__le64	tx_errors;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	__le32	rx_errors;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	__le16	rx_missed;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	__le16	align_errors;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	__le32	tx_one_collision;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	__le32	tx_multi_collision;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	__le64	rx_unicast;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	__le64	rx_broadcast;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	__le32	rx_multicast;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	__le16	tx_aborted;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	__le16	tx_underun;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
static int rtl8169_get_sset_count(struct net_device *dev, int sset)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	switch (sset) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	case ETH_SS_STATS:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
		return ARRAY_SIZE(rtl8169_gstrings);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	default:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		return -EOPNOTSUPP;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
static void rtl8169_get_ethtool_stats(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
				      struct ethtool_stats *stats, u64 *data)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	struct rtl8169_counters *counters;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	dma_addr_t paddr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	u32 cmd;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	ASSERT_RTNL();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	if (!counters)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		return;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	RTL_W32(CounterAddrHigh, (u64)paddr >> 32);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	cmd = (u64)paddr & DMA_32BIT_MASK;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	RTL_W32(CounterAddrLow, cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	RTL_W32(CounterAddrLow, cmd | CounterDump);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	while (RTL_R32(CounterAddrLow) & CounterDump) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
		if (msleep_interruptible(1))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	RTL_W32(CounterAddrLow, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	RTL_W32(CounterAddrHigh, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	data[0] = le64_to_cpu(counters->tx_packets);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	data[1] = le64_to_cpu(counters->rx_packets);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	data[2] = le64_to_cpu(counters->tx_errors);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	data[3] = le32_to_cpu(counters->rx_errors);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	data[4] = le16_to_cpu(counters->rx_missed);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	data[5] = le16_to_cpu(counters->align_errors);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	data[6] = le32_to_cpu(counters->tx_one_collision);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	data[7] = le32_to_cpu(counters->tx_multi_collision);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	data[8] = le64_to_cpu(counters->rx_unicast);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	data[9] = le64_to_cpu(counters->rx_broadcast);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	data[10] = le32_to_cpu(counters->rx_multicast);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	data[11] = le16_to_cpu(counters->tx_aborted);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	data[12] = le16_to_cpu(counters->tx_underun);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	switch(stringset) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	case ETH_SS_STATS:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		memcpy(data, *rtl8169_gstrings, sizeof(rtl8169_gstrings));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
static const struct ethtool_ops rtl8169_ethtool_ops = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	.get_drvinfo		= rtl8169_get_drvinfo,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	.get_regs_len		= rtl8169_get_regs_len,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	.get_link		= ethtool_op_get_link,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	.get_settings		= rtl8169_get_settings,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	.set_settings		= rtl8169_set_settings,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	.get_msglevel		= rtl8169_get_msglevel,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	.set_msglevel		= rtl8169_set_msglevel,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	.get_rx_csum		= rtl8169_get_rx_csum,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	.set_rx_csum		= rtl8169_set_rx_csum,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	.set_tx_csum		= ethtool_op_set_tx_csum,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	.set_sg			= ethtool_op_set_sg,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	.set_tso		= ethtool_op_set_tso,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	.get_regs		= rtl8169_get_regs,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	.get_wol		= rtl8169_get_wol,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	.set_wol		= rtl8169_set_wol,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	.get_strings		= rtl8169_get_strings,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	.get_sset_count		= rtl8169_get_sset_count,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
	.get_ethtool_stats	= rtl8169_get_ethtool_stats,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
				       int bitnum, int bitval)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	int val;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	val = mdio_read(ioaddr, reg);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	val = (bitval == 1) ?
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		val | (bitval << bitnum) :  val & ~(0x0001 << bitnum);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	mdio_write(ioaddr, reg, val & 0xffff);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
static void rtl8169_get_mac_version(struct rtl8169_private *tp,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
				    void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	 * The driver currently handles the 8168Bf and the 8168Be identically
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	 * but they can be identified more specifically through the test below
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	 * if needed:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	 *
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	 * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	 *
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	 * Same thing for the 8101Eb and the 8101Ec:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	 *
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	 * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	const struct {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
		u32 mask;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
		u32 val;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
		int mac_version;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
	} mac_info[] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		/* 8168B family. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
		{ 0x7c800000, 0x3c800000,	RTL_GIGA_MAC_VER_18 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
		{ 0x7cf00000, 0x3c000000,	RTL_GIGA_MAC_VER_19 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		{ 0x7cf00000, 0x3c200000,	RTL_GIGA_MAC_VER_20 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		{ 0x7c800000, 0x3c000000,	RTL_GIGA_MAC_VER_20 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		/* 8168B family. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		{ 0x7cf00000, 0x38000000,	RTL_GIGA_MAC_VER_12 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		{ 0x7cf00000, 0x38500000,	RTL_GIGA_MAC_VER_17 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		{ 0x7c800000, 0x38000000,	RTL_GIGA_MAC_VER_17 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		{ 0x7c800000, 0x30000000,	RTL_GIGA_MAC_VER_11 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
		/* 8101 family. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		{ 0x7cf00000, 0x34000000,	RTL_GIGA_MAC_VER_13 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		{ 0x7cf00000, 0x34200000,	RTL_GIGA_MAC_VER_16 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
		{ 0x7c800000, 0x34000000,	RTL_GIGA_MAC_VER_16 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
		/* FIXME: where did these entries come from ? -- FR */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		{ 0xfc800000, 0x38800000,	RTL_GIGA_MAC_VER_15 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		{ 0xfc800000, 0x30800000,	RTL_GIGA_MAC_VER_14 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		/* 8110 family. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		{ 0xfc800000, 0x98000000,	RTL_GIGA_MAC_VER_06 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		{ 0xfc800000, 0x18000000,	RTL_GIGA_MAC_VER_05 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		{ 0xfc800000, 0x10000000,	RTL_GIGA_MAC_VER_04 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		{ 0xfc800000, 0x04000000,	RTL_GIGA_MAC_VER_03 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		{ 0xfc800000, 0x00800000,	RTL_GIGA_MAC_VER_02 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		{ 0xfc800000, 0x00000000,	RTL_GIGA_MAC_VER_01 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		{ 0x00000000, 0x00000000,	RTL_GIGA_MAC_VER_01 }	/* Catch-all */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	}, *p = mac_info;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	u32 reg;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	reg = RTL_R32(TxConfig);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	while ((reg & p->mask) != p->val)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		p++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	tp->mac_version = p->mac_version;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
	if (p->mask == 0x00000000) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
		struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		dev_info(&pdev->dev, "unknown MAC (%08x)\n", reg);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
static void rtl8169_print_mac_version(struct rtl8169_private *tp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	dprintk("mac_version = 0x%02x\n", tp->mac_version);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
struct phy_reg {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	u16 reg;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	u16 val;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
static void rtl_phy_write(void __iomem *ioaddr, struct phy_reg *regs, int len)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	while (len-- > 0) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
		mdio_write(ioaddr, regs->reg, regs->val);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
		regs++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
static void rtl8169s_hw_phy_config(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	struct {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
		u16 regs[5]; /* Beware of bit-sign propagation */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	} phy_magic[5] = { {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		{ 0x0000,	//w 4 15 12 0
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		  0x00a1,	//w 3 15 0 00a1
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		  0x0008,	//w 2 15 0 0008
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		  0x1020,	//w 1 15 0 1020
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		  0x1000 } },{	//w 0 15 0 1000
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		{ 0x7000,	//w 4 15 12 7
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		  0xff41,	//w 3 15 0 ff41
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		  0xde60,	//w 2 15 0 de60
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		  0x0140,	//w 1 15 0 0140
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		  0x0077 } },{	//w 0 15 0 0077
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		{ 0xa000,	//w 4 15 12 a
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
		  0xdf01,	//w 3 15 0 df01
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
		  0xdf20,	//w 2 15 0 df20
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		  0xff95,	//w 1 15 0 ff95
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		  0xfa00 } },{	//w 0 15 0 fa00
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
		{ 0xb000,	//w 4 15 12 b
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		  0xff41,	//w 3 15 0 ff41
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		  0xde20,	//w 2 15 0 de20
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		  0x0140,	//w 1 15 0 0140
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		  0x00bb } },{	//w 0 15 0 00bb
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		{ 0xf000,	//w 4 15 12 f
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		  0xdf01,	//w 3 15 0 df01
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		  0xdf20,	//w 2 15 0 df20
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		  0xff95,	//w 1 15 0 ff95
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		  0xbf00 }	//w 0 15 0 bf00
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	}, *p = phy_magic;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
	unsigned int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	mdio_write(ioaddr, 0x1f, 0x0001);		//w 31 2 0 1
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	mdio_write(ioaddr, 0x15, 0x1000);		//w 21 15 0 1000
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	mdio_write(ioaddr, 0x18, 0x65c7);		//w 24 15 0 65c7
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0);	//w 4 11 11 0
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	for (i = 0; i < ARRAY_SIZE(phy_magic); i++, p++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		int val, pos = 4;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		val = (mdio_read(ioaddr, pos) & 0x0fff) | (p->regs[0] & 0xffff);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		mdio_write(ioaddr, pos, val);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		while (--pos >= 0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
			mdio_write(ioaddr, pos, p->regs[4 - pos] & 0xffff);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	mdio_write(ioaddr, 0x1f, 0x0000); //w 31 2 0 0
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
	struct phy_reg phy_reg_init[] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
		{ 0x1f, 0x0002 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
		{ 0x01, 0x90d0 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
		{ 0x1f, 0x0000 }
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
static void rtl8168cp_hw_phy_config(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	struct phy_reg phy_reg_init[] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
		{ 0x1f, 0x0000 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
		{ 0x1d, 0x0f00 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
		{ 0x1f, 0x0002 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
		{ 0x0c, 0x1ec8 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
		{ 0x1f, 0x0000 }
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
static void rtl8168c_hw_phy_config(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	struct phy_reg phy_reg_init[] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
		{ 0x1f, 0x0001 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
		{ 0x12, 0x2300 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
		{ 0x1f, 0x0002 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
		{ 0x00, 0x88d4 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
		{ 0x01, 0x82b1 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		{ 0x03, 0x7002 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
		{ 0x08, 0x9e30 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
		{ 0x09, 0x01f0 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
		{ 0x0a, 0x5500 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		{ 0x0c, 0x00c8 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
		{ 0x1f, 0x0003 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
		{ 0x12, 0xc096 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
		{ 0x16, 0x000a },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
		{ 0x1f, 0x0000 }
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	struct phy_reg phy_reg_init[] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
		{ 0x1f, 0x0000 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
		{ 0x12, 0x2300 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
		{ 0x1f, 0x0003 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		{ 0x16, 0x0f0a },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		{ 0x1f, 0x0000 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		{ 0x1f, 0x0002 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
		{ 0x0c, 0x7eb8 },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		{ 0x1f, 0x0000 }
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
static void rtl_hw_phy_config(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	rtl8169_print_mac_version(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
	switch (tp->mac_version) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	case RTL_GIGA_MAC_VER_01:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
		break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	case RTL_GIGA_MAC_VER_02:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	case RTL_GIGA_MAC_VER_03:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		rtl8169s_hw_phy_config(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
		break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
	case RTL_GIGA_MAC_VER_04:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
		rtl8169sb_hw_phy_config(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
		break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	case RTL_GIGA_MAC_VER_18:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
		rtl8168cp_hw_phy_config(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
		break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	case RTL_GIGA_MAC_VER_19:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
		rtl8168c_hw_phy_config(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
		break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	case RTL_GIGA_MAC_VER_20:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		rtl8168cx_hw_phy_config(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
		break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	default:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
		break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
static void rtl8169_phy_timer(unsigned long __opaque)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	struct net_device *dev = (struct net_device *)__opaque;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	struct timer_list *timer = &tp->timer;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	unsigned long timeout = RTL8169_PHY_TIMEOUT;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
		return;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	spin_lock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	if (tp->phy_reset_pending(ioaddr)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
		/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
		 * A busy loop could burn quite a few cycles on nowadays CPU.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
		 * Let's delay the execution of the timer for a few ticks.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
		timeout = HZ/10;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
		goto out_mod_timer;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	if (tp->link_ok(ioaddr))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
		goto out_unlock;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	if (netif_msg_link(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
		printk(KERN_WARNING "%s: PHY reset until link up\n", dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	tp->phy_reset_enable(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
out_mod_timer:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	mod_timer(timer, jiffies + timeout);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
out_unlock:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
	spin_unlock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
static inline void rtl8169_delete_timer(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	struct timer_list *timer = &tp->timer;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
		return;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	del_timer_sync(timer);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
static inline void rtl8169_request_timer(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	struct timer_list *timer = &tp->timer;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
		return;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
#ifdef CONFIG_NET_POLL_CONTROLLER
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
 * Polling 'interrupt' - used by things like netconsole to send skbs
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
 * without having to re-enable interrupts. It's not called while
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
 * the interrupt routine is executing.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
static void rtl8169_netpoll(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
	struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	disable_irq(pdev->irq);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
	rtl8169_interrupt(pdev->irq, dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	enable_irq(pdev->irq);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
				  void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	iounmap(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	pci_release_regions(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	pci_disable_device(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	free_netdev(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
static void rtl8169_phy_reset(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
			      struct rtl8169_private *tp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	unsigned int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	tp->phy_reset_enable(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
	for (i = 0; i < 100; i++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
		if (!tp->phy_reset_pending(ioaddr))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
			return;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
		msleep(1);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	if (netif_msg_link(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
		printk(KERN_ERR "%s: PHY reset failed.\n", dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	rtl_hw_phy_config(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	RTL_W8(0x82, 0x01);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
		pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
		dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		RTL_W8(0x82, 0x01);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		dprintk("Set PHY Reg 0x0bh = 0x00h\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
		mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
	rtl8169_phy_reset(dev, tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	 * rtl8169_set_speed_xmii takes good care of the Fast Ethernet
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	 * only 8101. Don't panic.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
	 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
		printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	u32 high;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
	u32 low;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	low  = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	high = addr[4] | (addr[5] << 8);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	spin_lock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	RTL_W8(Cfg9346, Cfg9346_Unlock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	RTL_W32(MAC0, low);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	RTL_W32(MAC4, high);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	RTL_W8(Cfg9346, Cfg9346_Lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	spin_unlock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
static int rtl_set_mac_address(struct net_device *dev, void *p)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	struct sockaddr *addr = p;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	if (!is_valid_ether_addr(addr->sa_data))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		return -EADDRNOTAVAIL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
	rtl_rar_set(tp, dev->dev_addr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	struct mii_ioctl_data *data = if_mii(ifr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	if (!netif_running(dev))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		return -ENODEV;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	switch (cmd) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	case SIOCGMIIPHY:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		data->phy_id = 32; /* Internal PHY */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
		return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	case SIOCGMIIREG:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
		data->val_out = mdio_read(tp->mmio_addr, data->reg_num & 0x1f);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
		return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	case SIOCSMIIREG:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
		if (!capable(CAP_NET_ADMIN))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
			return -EPERM;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		mdio_write(tp->mmio_addr, data->reg_num & 0x1f, data->val_in);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	return -EOPNOTSUPP;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
static const struct rtl_cfg_info {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	void (*hw_start)(struct net_device *);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	unsigned int region;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	unsigned int align;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	u16 intr_event;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	u16 napi_event;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	unsigned msi;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
} rtl_cfg_infos [] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	[RTL_CFG_0] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
		.hw_start	= rtl_hw_start_8169,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
		.region		= 1,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
		.align		= 0,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		.intr_event	= SYSErr | LinkChg | RxOverflow |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		.msi		= 0
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	},
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	[RTL_CFG_1] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		.hw_start	= rtl_hw_start_8168,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		.region		= 2,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		.align		= 8,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		.intr_event	= SYSErr | LinkChg | RxOverflow |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
				  TxErr | TxOK | RxOK | RxErr,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		.napi_event	= TxErr | TxOK | RxOK | RxOverflow,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		.msi		= RTL_FEATURE_MSI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	},
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
	[RTL_CFG_2] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
		.hw_start	= rtl_hw_start_8101,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		.region		= 2,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
		.align		= 8,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		.intr_event	= SYSErr | LinkChg | RxOverflow | PCSTimeout |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		.msi		= RTL_FEATURE_MSI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
/* Cfg9346_Unlock assumed. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
			    const struct rtl_cfg_info *cfg)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	unsigned msi = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
	u8 cfg2;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	cfg2 = RTL_R8(Config2) & ~MSIEnable;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	if (cfg->msi) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
		if (pci_enable_msi(pdev)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
			dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
		} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
			cfg2 |= MSIEnable;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
			msi = RTL_FEATURE_MSI;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	RTL_W8(Config2, cfg2);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	return msi;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
	if (tp->features & RTL_FEATURE_MSI) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
		pci_disable_msi(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
		tp->features &= ~RTL_FEATURE_MSI;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
static int __devinit
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	const unsigned int region = cfg->region;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	struct rtl8169_private *tp;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	struct net_device *dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	void __iomem *ioaddr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	unsigned int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	int rc;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	if (netif_msg_drv(&debug)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		       MODULENAME, RTL8169_VERSION);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	dev = alloc_etherdev(sizeof (*tp));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	if (!dev) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		if (netif_msg_drv(&debug))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
			dev_err(&pdev->dev, "unable to alloc new ethernet\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
		rc = -ENOMEM;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	SET_NETDEV_DEV(dev, &pdev->dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
	tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	tp->dev = dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
	/* enable device (incl. PCI PM wakeup and hotplug setup) */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
	rc = pci_enable_device(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
	if (rc < 0) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		if (netif_msg_probe(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
			dev_err(&pdev->dev, "enable failure\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		goto err_out_free_dev_1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	rc = pci_set_mwi(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	if (rc < 0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		goto err_out_disable_2;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
	/* make sure PCI base addr 1 is MMIO */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
	if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		if (netif_msg_probe(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
			dev_err(&pdev->dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
				"region #%d not an MMIO resource, aborting\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
				region);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		rc = -ENODEV;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		goto err_out_mwi_3;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
	/* check for weird/broken PCI region reporting */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
	if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
		if (netif_msg_probe(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
			dev_err(&pdev->dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
				"Invalid PCI region size(s), aborting\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		rc = -ENODEV;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		goto err_out_mwi_3;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	rc = pci_request_regions(pdev, MODULENAME);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	if (rc < 0) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
		if (netif_msg_probe(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
			dev_err(&pdev->dev, "could not request regions.\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
		goto err_out_mwi_3;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
	tp->cp_cmd = PCIMulRW | RxChkSum;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
	if ((sizeof(dma_addr_t) > 4) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK) && use_dac) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
		tp->cp_cmd |= PCIDAC;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
		dev->features |= NETIF_F_HIGHDMA;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		if (rc < 0) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			if (netif_msg_probe(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
				dev_err(&pdev->dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
					"DMA configuration failed.\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
			}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
			goto err_out_free_res_4;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	pci_set_master(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	/* ioremap MMIO region */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	if (!ioaddr) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
		if (netif_msg_probe(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
			dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
		rc = -EIO;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
		goto err_out_free_res_4;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	/* Unneeded ? Don't mess with Mrs. Murphy. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
	rtl8169_irq_mask_and_ack(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	/* Soft reset the chip. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	RTL_W8(ChipCmd, CmdReset);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	/* Check that the chip has finished the reset. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	for (i = 0; i < 100; i++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
		msleep_interruptible(1);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	/* Identify chip attached to board */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	rtl8169_get_mac_version(tp, ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	rtl8169_print_mac_version(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		if (tp->mac_version == rtl_chip_info[i].mac_version)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	if (i < 0) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
		/* Unknown chip: assume array element #0, original RTL-8169 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
		if (netif_msg_probe(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
			dev_printk(KERN_DEBUG, &pdev->dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
				"unknown chip version, assuming %s\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
				rtl_chip_info[0].name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
		i++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	tp->chipset = i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	RTL_W8(Cfg9346, Cfg9346_Unlock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
	tp->features |= rtl_try_msi(pdev, ioaddr, cfg);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	RTL_W8(Cfg9346, Cfg9346_Lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
	if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	    (RTL_R8(PHYstatus) & TBI_Enable)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		tp->set_speed = rtl8169_set_speed_tbi;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		tp->get_settings = rtl8169_gset_tbi;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
		tp->phy_reset_enable = rtl8169_tbi_reset_enable;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		tp->phy_reset_pending = rtl8169_tbi_reset_pending;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		tp->link_ok = rtl8169_tbi_link_ok;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		tp->set_speed = rtl8169_set_speed_xmii;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		tp->get_settings = rtl8169_gset_xmii;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		tp->phy_reset_enable = rtl8169_xmii_reset_enable;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		tp->phy_reset_pending = rtl8169_xmii_reset_pending;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		tp->link_ok = rtl8169_xmii_link_ok;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		dev->do_ioctl = rtl8169_ioctl;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	/* Get MAC address.  FIXME: read EEPROM */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	for (i = 0; i < MAC_ADDR_LEN; i++)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
		dev->dev_addr[i] = RTL_R8(MAC0 + i);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	dev->open = rtl8169_open;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	dev->hard_start_xmit = rtl8169_start_xmit;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	dev->get_stats = rtl8169_get_stats;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
	dev->stop = rtl8169_close;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	dev->tx_timeout = rtl8169_tx_timeout;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	dev->set_multicast_list = rtl_set_rx_mode;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	dev->irq = pdev->irq;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	dev->base_addr = (unsigned long) ioaddr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	dev->change_mtu = rtl8169_change_mtu;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	dev->set_mac_address = rtl_set_mac_address;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
#ifdef CONFIG_R8169_VLAN
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	dev->vlan_rx_register = rtl8169_vlan_rx_register;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
#ifdef CONFIG_NET_POLL_CONTROLLER
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
	dev->poll_controller = rtl8169_netpoll;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	tp->intr_mask = 0xffff;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
	tp->pci_dev = pdev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	tp->mmio_addr = ioaddr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
	tp->align = cfg->align;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	tp->hw_start = cfg->hw_start;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
	tp->intr_event = cfg->intr_event;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	tp->napi_event = cfg->napi_event;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
	init_timer(&tp->timer);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	tp->timer.data = (unsigned long) dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
	tp->timer.function = rtl8169_phy_timer;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
	spin_lock_init(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	rc = register_netdev(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
	if (rc < 0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		goto err_out_msi_5;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	pci_set_drvdata(pdev, dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	if (netif_msg_probe(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
		u32 xid = RTL_R32(TxConfig) & 0x7cf0f8ff;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
		printk(KERN_INFO "%s: %s at 0x%lx, "
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
		       "XID %08x IRQ %d\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
		       dev->name,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		       rtl_chip_info[tp->chipset].name,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
		       dev->base_addr,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
		       dev->dev_addr[0], dev->dev_addr[1],
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
		       dev->dev_addr[2], dev->dev_addr[3],
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
		       dev->dev_addr[4], dev->dev_addr[5], xid, dev->irq);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	rtl8169_init_phy(dev, tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	return rc;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
err_out_msi_5:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
	rtl_disable_msi(pdev, tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
	iounmap(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
err_out_free_res_4:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	pci_release_regions(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
err_out_mwi_3:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
	pci_clear_mwi(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
err_out_disable_2:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
	pci_disable_device(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
err_out_free_dev_1:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	free_netdev(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	struct net_device *dev = pci_get_drvdata(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	flush_scheduled_work();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	unregister_netdev(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
	rtl_disable_msi(pdev, tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	rtl8169_release_board(pdev, dev, tp->mmio_addr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
	pci_set_drvdata(pdev, NULL);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
				  struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	unsigned int mtu = dev->mtu;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
static int rtl8169_open(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	int retval = -ENOMEM;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
	rtl8169_set_rxbufsize(tp, dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	 * Rx and Tx desscriptors needs 256 bytes alignment.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
	 * pci_alloc_consistent provides more.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
	 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
					       &tp->TxPhyAddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	if (!tp->TxDescArray)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
		goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
					       &tp->RxPhyAddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	if (!tp->RxDescArray)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
		goto err_free_tx_0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	retval = rtl8169_init_ring(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	if (retval < 0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		goto err_free_rx_1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	INIT_DELAYED_WORK(&tp->task, NULL);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
	smp_mb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	retval = request_irq(dev->irq, rtl8169_interrupt,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
			     (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
			     dev->name, dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
	if (retval < 0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		goto err_release_ring_2;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	napi_enable(&tp->napi);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
	rtl_hw_start(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	rtl8169_request_timer(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	rtl8169_check_link_status(dev, tp, tp->mmio_addr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
	return retval;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
err_release_ring_2:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	rtl8169_rx_clear(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
err_free_rx_1:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
			    tp->RxPhyAddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
err_free_tx_0:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
			    tp->TxPhyAddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
static void rtl8169_hw_reset(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
	/* Disable interrupts */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	rtl8169_irq_mask_and_ack(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	/* Reset the chipset */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	RTL_W8(ChipCmd, CmdReset);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	/* PCI commit */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	RTL_R8(ChipCmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	u32 cfg = rtl8169_rx_config;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	RTL_W32(RxConfig, cfg);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	/* Set DMA burst size and Interframe Gap Time */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
		(InterFrameGap << TxInterFrameGapShift));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
static void rtl_hw_start(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	unsigned int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
	/* Soft reset the chip. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	RTL_W8(ChipCmd, CmdReset);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	/* Check that the chip has finished the reset. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	for (i = 0; i < 100; i++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
		msleep_interruptible(1);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	tp->hw_start(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	netif_start_queue(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
					 void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	 * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	 * register to be written before TxDescAddrLow to work.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
	 * Switching from MMIO to I/O access fixes the issue as well.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
	RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
	RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
	RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	u16 cmd;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
	cmd = RTL_R16(CPlusCmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
	RTL_W16(CPlusCmd, cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	return cmd;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
static void rtl_set_rx_max_size(void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	/* Low hurts. Let's disable the filtering. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
	RTL_W16(RxMaxSize, 16383);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	struct {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
		u32 mac_version;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
		u32 clk;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
		u32 val;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	} cfg2_info [] = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
		{ RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
		{ RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff },
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		{ RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		{ RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff }
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	}, *p = cfg2_info;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
	unsigned int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	u32 clk;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	clk = RTL_R8(Config2) & PCI_Clock_66MHz;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	for (i = 0; i < ARRAY_SIZE(cfg2_info); i++, p++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
		if ((p->mac_version == mac_version) && (p->clk == clk)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
			RTL_W32(0x7c, p->val);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
static void rtl_hw_start_8169(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
		RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	RTL_W8(Cfg9346, Cfg9346_Unlock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	    (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
	    (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	    (tp->mac_version == RTL_GIGA_MAC_VER_04))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	RTL_W8(EarlyTxThres, EarlyTxThld);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	rtl_set_rx_max_size(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	    (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	    (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	    (tp->mac_version == RTL_GIGA_MAC_VER_04))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
		rtl_set_rx_tx_config_registers(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
	    (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
		dprintk("Set MAC Reg C+CR Offset 0xE0. "
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
			"Bit-3 and bit-14 MUST be 1\n");
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
		tp->cp_cmd |= (1 << 14);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
	RTL_W16(CPlusCmd, tp->cp_cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
	rtl8169_set_magic_reg(ioaddr, tp->mac_version);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
	 * Undocumented corner. Supposedly:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
	 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
	 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	RTL_W16(IntrMitigate, 0x0000);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	rtl_set_rx_tx_desc_registers(tp, ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	    (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
	    (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	    (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
		rtl_set_rx_tx_config_registers(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	RTL_W8(Cfg9346, Cfg9346_Lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	/* Initially a 10 us delay. Turned it into a PCI commit. - FR */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
	RTL_R8(IntrMask);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	RTL_W32(RxMissed, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
	rtl_set_rx_mode(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	/* no early-rx interrupts */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	/* Enable all known interrupts by setting the interrupt mask. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	RTL_W16(IntrMask, tp->intr_event);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
static void rtl_hw_start_8168(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
	struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
	u8 ctl;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	RTL_W8(Cfg9346, Cfg9346_Unlock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	RTL_W8(EarlyTxThres, EarlyTxThld);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	rtl_set_rx_max_size(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	rtl_set_rx_tx_config_registers(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	RTL_W16(CPlusCmd, tp->cp_cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	/* Tx performance tweak. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	pci_read_config_byte(pdev, 0x69, &ctl);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	ctl = (ctl & ~0x70) | 0x50;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
	pci_write_config_byte(pdev, 0x69, ctl);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	RTL_W16(IntrMitigate, 0x5151);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
	/* Work around for RxFIFO overflow. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
	if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		tp->intr_event |= RxFIFOOver | PCSTimeout;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
		tp->intr_event &= ~RxOverflow;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	rtl_set_rx_tx_desc_registers(tp, ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	RTL_W8(Cfg9346, Cfg9346_Lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
	RTL_R8(IntrMask);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
	RTL_W32(RxMissed, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
	rtl_set_rx_mode(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	RTL_W16(IntrMask, tp->intr_event);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
static void rtl_hw_start_8101(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
	if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
	    (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
		pci_write_config_word(pdev, 0x68, 0x00);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
		pci_write_config_word(pdev, 0x69, 0x08);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
	RTL_W8(Cfg9346, Cfg9346_Unlock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
	RTL_W8(EarlyTxThres, EarlyTxThld);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	rtl_set_rx_max_size(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	RTL_W16(CPlusCmd, tp->cp_cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	RTL_W16(IntrMitigate, 0x0000);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	rtl_set_rx_tx_desc_registers(tp, ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	rtl_set_rx_tx_config_registers(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	RTL_W8(Cfg9346, Cfg9346_Lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
	RTL_R8(IntrMask);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	RTL_W32(RxMissed, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	rtl_set_rx_mode(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
	RTL_W16(IntrMask, tp->intr_event);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	int ret = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
	if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
		return -EINVAL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
	dev->mtu = new_mtu;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	if (!netif_running(dev))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
		goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
	rtl8169_down(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	rtl8169_set_rxbufsize(tp, dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
	ret = rtl8169_init_ring(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	if (ret < 0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
		goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	napi_enable(&tp->napi);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	rtl_hw_start(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	rtl8169_request_timer(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	return ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	desc->addr = cpu_to_le64(0x0badbadbadbadbadull);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
	desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
static void rtl8169_free_rx_skb(struct rtl8169_private *tp,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
				struct sk_buff **sk_buff, struct RxDesc *desc)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
			 PCI_DMA_FROMDEVICE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	dev_kfree_skb(*sk_buff);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	*sk_buff = NULL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
	rtl8169_make_unusable_by_asic(desc);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
static inline void rtl8169_mark_to_asic(struct RxDesc *desc, u32 rx_buf_sz)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	u32 eor = le32_to_cpu(desc->opts1) & RingEnd;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	desc->opts1 = cpu_to_le32(DescOwn | eor | rx_buf_sz);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
				       u32 rx_buf_sz)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	desc->addr = cpu_to_le64(mapping);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	wmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	rtl8169_mark_to_asic(desc, rx_buf_sz);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
					    struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
					    struct RxDesc *desc, int rx_buf_sz,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
					    unsigned int align)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	struct sk_buff *skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	dma_addr_t mapping;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	unsigned int pad;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
	pad = align ? align : NET_IP_ALIGN;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	skb = netdev_alloc_skb(dev, rx_buf_sz + pad);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	if (!skb)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
		goto err_out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
				 PCI_DMA_FROMDEVICE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	return skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
err_out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	rtl8169_make_unusable_by_asic(desc);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
	goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
static void rtl8169_rx_clear(struct rtl8169_private *tp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	unsigned int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	for (i = 0; i < NUM_RX_DESC; i++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
		if (tp->Rx_skbuff[i]) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
			rtl8169_free_rx_skb(tp, tp->Rx_skbuff + i,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
					    tp->RxDescArray + i);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
			   u32 start, u32 end)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	u32 cur;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	for (cur = start; end - cur != 0; cur++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
		struct sk_buff *skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
		unsigned int i = cur % NUM_RX_DESC;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
		WARN_ON((s32)(end - cur) < 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
		if (tp->Rx_skbuff[i])
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
			continue;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
		skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
					   tp->RxDescArray + i,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
					   tp->rx_buf_sz, tp->align);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
		if (!skb)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
		tp->Rx_skbuff[i] = skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	return cur - start;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	desc->opts1 |= cpu_to_le32(RingEnd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
static int rtl8169_init_ring(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	rtl8169_init_ring_indexes(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		goto err_out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
	rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
err_out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	rtl8169_rx_clear(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	return -ENOMEM;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
				 struct TxDesc *desc)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	unsigned int len = tx_skb->len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
	desc->opts1 = 0x00;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
	desc->opts2 = 0x00;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	desc->addr = 0x00;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
	tx_skb->len = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
static void rtl8169_tx_clear(struct rtl8169_private *tp)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	unsigned int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	for (i = tp->dirty_tx; i < tp->dirty_tx + NUM_TX_DESC; i++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
		unsigned int entry = i % NUM_TX_DESC;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
		struct ring_info *tx_skb = tp->tx_skb + entry;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
		unsigned int len = tx_skb->len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
		if (len) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
			struct sk_buff *skb = tx_skb->skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
			rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
					     tp->TxDescArray + entry);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
			if (skb) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
				dev_kfree_skb(skb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
				tx_skb->skb = NULL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
			}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
			tp->dev->stats.tx_dropped++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
	tp->cur_tx = tp->dirty_tx = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
static void rtl8169_schedule_work(struct net_device *dev, work_func_t task)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
	PREPARE_DELAYED_WORK(&tp->task, task);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	schedule_delayed_work(&tp->task, 4);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
static void rtl8169_wait_for_quiescence(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
	synchronize_irq(dev->irq);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	/* Wait for any pending NAPI task to complete */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	napi_disable(&tp->napi);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
	rtl8169_irq_mask_and_ack(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	tp->intr_mask = 0xffff;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	RTL_W16(IntrMask, tp->intr_event);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	napi_enable(&tp->napi);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
static void rtl8169_reinit_task(struct work_struct *work)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
	struct rtl8169_private *tp =
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
		container_of(work, struct rtl8169_private, task.work);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
	struct net_device *dev = tp->dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
	int ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
	rtnl_lock();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	if (!netif_running(dev))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
		goto out_unlock;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	rtl8169_wait_for_quiescence(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	rtl8169_close(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	ret = rtl8169_open(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
	if (unlikely(ret < 0)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
		if (net_ratelimit() && netif_msg_drv(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
			printk(KERN_ERR PFX "%s: reinit failure (status = %d)."
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
			       " Rescheduling.\n", dev->name, ret);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
		rtl8169_schedule_work(dev, rtl8169_reinit_task);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
out_unlock:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
	rtnl_unlock();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
static void rtl8169_reset_task(struct work_struct *work)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
	struct rtl8169_private *tp =
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
		container_of(work, struct rtl8169_private, task.work);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	struct net_device *dev = tp->dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	rtnl_lock();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	if (!netif_running(dev))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
		goto out_unlock;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	rtl8169_wait_for_quiescence(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	rtl8169_rx_interrupt(dev, tp, tp->mmio_addr, ~(u32)0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	rtl8169_tx_clear(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	if (tp->dirty_rx == tp->cur_rx) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
		rtl8169_init_ring_indexes(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
		rtl_hw_start(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
		netif_wake_queue(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		rtl8169_check_link_status(dev, tp, tp->mmio_addr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		if (net_ratelimit() && netif_msg_intr(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
			printk(KERN_EMERG PFX "%s: Rx buffers shortage\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
			       dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
		rtl8169_schedule_work(dev, rtl8169_reset_task);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
out_unlock:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
	rtnl_unlock();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
static void rtl8169_tx_timeout(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	rtl8169_hw_reset(tp->mmio_addr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	/* Let's wait a bit while any (async) irq lands on */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	rtl8169_schedule_work(dev, rtl8169_reset_task);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
			      u32 opts1)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	struct skb_shared_info *info = skb_shinfo(skb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
	unsigned int cur_frag, entry;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	struct TxDesc * uninitialized_var(txd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	entry = tp->cur_tx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
	for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
		skb_frag_t *frag = info->frags + cur_frag;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
		dma_addr_t mapping;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
		u32 status, len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
		void *addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
		entry = (entry + 1) % NUM_TX_DESC;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		txd = tp->TxDescArray + entry;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
		len = frag->size;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
		addr = ((void *) page_address(frag->page)) + frag->page_offset;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		mapping = pci_map_single(tp->pci_dev, addr, len, PCI_DMA_TODEVICE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		/* anti gcc 2.95.3 bugware (sic) */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
		status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
		txd->opts1 = cpu_to_le32(status);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		txd->addr = cpu_to_le64(mapping);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		tp->tx_skb[entry].len = len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
	if (cur_frag) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		tp->tx_skb[entry].skb = skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		txd->opts1 |= cpu_to_le32(LastFrag);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	return cur_frag;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	if (dev->features & NETIF_F_TSO) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
		u32 mss = skb_shinfo(skb)->gso_size;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
		if (mss)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
			return LargeSend | ((mss & MSSMask) << MSSShift);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
	if (skb->ip_summed == CHECKSUM_PARTIAL) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
		const struct iphdr *ip = ip_hdr(skb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		if (ip->protocol == IPPROTO_TCP)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
			return IPCS | TCPCS;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		else if (ip->protocol == IPPROTO_UDP)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
			return IPCS | UDPCS;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
		WARN_ON(1);	/* we need a WARN() */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
	unsigned int frags, entry = tp->cur_tx % NUM_TX_DESC;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	struct TxDesc *txd = tp->TxDescArray + entry;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
	dma_addr_t mapping;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
	u32 status, len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	u32 opts1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	int ret = NETDEV_TX_OK;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
	if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
		if (netif_msg_drv(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
			printk(KERN_ERR
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
			       "%s: BUG! Tx Ring full when queue awake!\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
			       dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
		goto err_stop;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
		goto err_stop;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	opts1 = DescOwn | rtl8169_tso_csum(skb, dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
	frags = rtl8169_xmit_frags(tp, skb, opts1);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	if (frags) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
		len = skb_headlen(skb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
		opts1 |= FirstFrag;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
	} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
		len = skb->len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
		if (unlikely(len < ETH_ZLEN)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
			if (skb_padto(skb, ETH_ZLEN))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
				goto err_update_stats;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
			len = ETH_ZLEN;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		opts1 |= FirstFrag | LastFrag;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
		tp->tx_skb[entry].skb = skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
	tp->tx_skb[entry].len = len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
	txd->addr = cpu_to_le64(mapping);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
	wmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	/* anti gcc 2.95.3 bugware (sic) */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	txd->opts1 = cpu_to_le32(status);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	dev->trans_start = jiffies;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
	tp->cur_tx += frags + 1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
	smp_wmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
	RTL_W8(TxPoll, NPQ);	/* set polling bit */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
	if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
		netif_stop_queue(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
		smp_rmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
			netif_wake_queue(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
	return ret;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
err_stop:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
	netif_stop_queue(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
	ret = NETDEV_TX_BUSY;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
err_update_stats:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
	dev->stats.tx_dropped++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
static void rtl8169_pcierr_interrupt(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	u16 pci_status, pci_cmd;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	pci_read_config_word(pdev, PCI_STATUS, &pci_status);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	if (netif_msg_intr(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
		printk(KERN_ERR
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
		       "%s: PCI error (cmd = 0x%04x, status = 0x%04x).\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
		       dev->name, pci_cmd, pci_status);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	 * The recovery sequence below admits a very elaborated explanation:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	 * - it seems to work;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	 * - I did not see what else could be done;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	 * - it makes iop3xx happy.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	 *
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
	 * Feel free to adjust to your needs.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	if (pdev->broken_parity_status)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
		pci_cmd &= ~PCI_COMMAND_PARITY;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
		pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
	pci_write_config_word(pdev, PCI_STATUS,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		pci_status & (PCI_STATUS_DETECTED_PARITY |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
		PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_REC_MASTER_ABORT |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_SIG_TARGET_ABORT));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
	/* The infamous DAC f*ckup only happens at boot time */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
		if (netif_msg_intr(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
			printk(KERN_INFO "%s: disabling PCI DAC.\n", dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
		tp->cp_cmd &= ~PCIDAC;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
		RTL_W16(CPlusCmd, tp->cp_cmd);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
		dev->features &= ~NETIF_F_HIGHDMA;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	rtl8169_hw_reset(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	rtl8169_schedule_work(dev, rtl8169_reinit_task);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
static void rtl8169_tx_interrupt(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
				 struct rtl8169_private *tp,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
				 void __iomem *ioaddr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	unsigned int dirty_tx, tx_left;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	dirty_tx = tp->dirty_tx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	smp_rmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	tx_left = tp->cur_tx - dirty_tx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	while (tx_left > 0) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		unsigned int entry = dirty_tx % NUM_TX_DESC;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
		struct ring_info *tx_skb = tp->tx_skb + entry;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
		u32 len = tx_skb->len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
		u32 status;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
		rmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
		status = le32_to_cpu(tp->TxDescArray[entry].opts1);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
		if (status & DescOwn)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
		dev->stats.tx_bytes += len;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
		dev->stats.tx_packets++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
		rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		if (status & LastFrag) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
			dev_kfree_skb_irq(tx_skb->skb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
			tx_skb->skb = NULL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
		dirty_tx++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
		tx_left--;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	if (tp->dirty_tx != dirty_tx) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		tp->dirty_tx = dirty_tx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
		smp_wmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		if (netif_queue_stopped(dev) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
		    (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
			netif_wake_queue(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
		/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
		 * 8168 hack: TxPoll requests are lost when the Tx packets are
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
		 * too close. Let's kick an extra TxPoll request when a burst
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
		 * of start_xmit activity is detected (if it is not detected,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		 * it is slow enough). -- FR
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
		 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
		smp_rmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
		if (tp->cur_tx != dirty_tx)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
			RTL_W8(TxPoll, NPQ);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
static inline int rtl8169_fragmented_frame(u32 status)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	u32 opts1 = le32_to_cpu(desc->opts1);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
	u32 status = opts1 & RxProtoMask;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
	    ((status == RxProtoUDP) && !(opts1 & UDPFail)) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	    ((status == RxProtoIP) && !(opts1 & IPFail)))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
		skb->ip_summed = CHECKSUM_UNNECESSARY;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
	else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
		skb->ip_summed = CHECKSUM_NONE;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
				       struct rtl8169_private *tp, int pkt_size,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
				       dma_addr_t addr)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	struct sk_buff *skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	bool done = false;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	if (pkt_size >= rx_copybreak)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
		goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	skb = netdev_alloc_skb(tp->dev, pkt_size + NET_IP_ALIGN);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	if (!skb)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
		goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
				    PCI_DMA_FROMDEVICE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	skb_reserve(skb, NET_IP_ALIGN);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
	skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
	*sk_buff = skb;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
	done = true;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	return done;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
static int rtl8169_rx_interrupt(struct net_device *dev,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
				struct rtl8169_private *tp,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
				void __iomem *ioaddr, u32 budget)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
	unsigned int cur_rx, rx_left;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	unsigned int delta, count;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
	cur_rx = tp->cur_rx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
	rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	rx_left = rtl8169_rx_quota(rx_left, budget);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
	for (; rx_left > 0; rx_left--, cur_rx++) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		unsigned int entry = cur_rx % NUM_RX_DESC;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		struct RxDesc *desc = tp->RxDescArray + entry;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		u32 status;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		rmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		status = le32_to_cpu(desc->opts1);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		if (status & DescOwn)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		if (unlikely(status & RxRES)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
			if (netif_msg_rx_err(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
				printk(KERN_INFO
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
				       "%s: Rx ERROR. status = %08x\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
				       dev->name, status);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
			}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
			dev->stats.rx_errors++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
			if (status & (RxRWT | RxRUNT))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
				dev->stats.rx_length_errors++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
			if (status & RxCRC)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
				dev->stats.rx_crc_errors++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
			if (status & RxFOVF) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
				rtl8169_schedule_work(dev, rtl8169_reset_task);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
				dev->stats.rx_fifo_errors++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
			}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
			rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
		} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
			struct sk_buff *skb = tp->Rx_skbuff[entry];
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
			dma_addr_t addr = le64_to_cpu(desc->addr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
			int pkt_size = (status & 0x00001FFF) - 4;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
			struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
			/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
			 * The driver does not support incoming fragmented
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
			 * frames. They are seen as a symptom of over-mtu
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
			 * sized frames.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
			 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
			if (unlikely(rtl8169_fragmented_frame(status))) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
				dev->stats.rx_dropped++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
				dev->stats.rx_length_errors++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
				rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
				continue;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
			}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
			rtl8169_rx_csum(skb, desc);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
			if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
				pci_dma_sync_single_for_device(pdev, addr,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
					pkt_size, PCI_DMA_FROMDEVICE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
				rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
			} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
				pci_unmap_single(pdev, addr, pkt_size,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
						 PCI_DMA_FROMDEVICE);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
				tp->Rx_skbuff[entry] = NULL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
			}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
			skb_put(skb, pkt_size);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
			skb->protocol = eth_type_trans(skb, dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
			if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
				rtl8169_rx_skb(skb);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
			dev->last_rx = jiffies;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
			dev->stats.rx_bytes += pkt_size;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
			dev->stats.rx_packets++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
		/* Work around for AMD plateform. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		if ((desc->opts2 & cpu_to_le32(0xfffe000)) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
		    (tp->mac_version == RTL_GIGA_MAC_VER_05)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
			desc->opts2 = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
			cur_rx++;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
	count = cur_rx - tp->cur_rx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
	tp->cur_rx = cur_rx;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
	delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
	if (!delta && count && netif_msg_intr(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
		printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	tp->dirty_rx += delta;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
	/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
	 * FIXME: until there is periodic timer to try and refill the ring,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
	 * a temporary shortage may definitely kill the Rx process.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	 * - disable the asic to try and avoid an overflow and kick it again
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	 *   after refill ?
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
	 * - how do others driver handle this condition (Uh oh...).
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	if ((tp->dirty_rx + NUM_RX_DESC == tp->cur_rx) && netif_msg_intr(tp))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
		printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	return count;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
	struct net_device *dev = dev_instance;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	int boguscnt = max_interrupt_work;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
	int status;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
	int handled = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
	do {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
		status = RTL_R16(IntrStatus);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
		/* hotplug/major error/no more work/shared irq */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		if ((status == 0xFFFF) || !status)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
		handled = 1;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
		if (unlikely(!netif_running(dev))) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
			rtl8169_asic_down(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
			goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		status &= tp->intr_mask;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		RTL_W16(IntrStatus,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
			(status & RxFIFOOver) ? (status | RxOverflow) : status);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		if (!(status & tp->intr_event))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
                /* Work around for rx fifo overflow */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
                if (unlikely(status & RxFIFOOver) &&
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
		    (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
			netif_stop_queue(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
			rtl8169_tx_timeout(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
		if (unlikely(status & SYSErr)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
			rtl8169_pcierr_interrupt(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
			break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
		if (status & LinkChg)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
			rtl8169_check_link_status(dev, tp, ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
		if (status & tp->napi_event) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
			RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
			tp->intr_mask = ~tp->napi_event;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
		if (likely(netif_rx_schedule_prep(dev, &tp->napi)))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
			__netif_rx_schedule(dev, &tp->napi);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
			else if (netif_msg_intr(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
				printk(KERN_INFO "%s: interrupt %04x in poll\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
				       dev->name, status);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
			}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		break;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
#else
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		/* Rx interrupt */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		if (status & (RxOK | RxOverflow | RxFIFOOver))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
			rtl8169_rx_interrupt(dev, tp, ioaddr, ~(u32)0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
		/* Tx interrupt */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		if (status & (TxOK | TxErr))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
			rtl8169_tx_interrupt(dev, tp, ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		boguscnt--;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	} while (boguscnt > 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	if (boguscnt <= 0) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
		if (netif_msg_intr(tp) && net_ratelimit() ) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
			printk(KERN_WARNING
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
			       "%s: Too much work at interrupt!\n", dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
		/* Clear all interrupt sources. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
		RTL_W16(IntrStatus, 0xffff);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	return IRQ_RETVAL(handled);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
static int rtl8169_poll(struct napi_struct *napi, int budget)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
	struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	struct net_device *dev = tp->dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	int work_done;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
	work_done = rtl8169_rx_interrupt(dev, tp, ioaddr, (u32) budget);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	rtl8169_tx_interrupt(dev, tp, ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
	if (work_done < budget) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		netif_rx_complete(dev, napi);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		tp->intr_mask = 0xffff;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
		/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
		 * 20040426: the barrier is not strictly required but the
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		 * behavior of the irq handler could be less predictable
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
		 * without it. Btw, the lack of flush for the posted pci
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
		 * write is safe - FR
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
		 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
		smp_wmb();
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
		RTL_W16(IntrMask, tp->intr_event);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
	return work_done;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
static void rtl8169_down(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
	unsigned int intrmask;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
	rtl8169_delete_timer(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
	netif_stop_queue(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
#ifdef CONFIG_R8169_NAPI
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	napi_disable(&tp->napi);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
core_down:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	spin_lock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	rtl8169_asic_down(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	/* Update the error counts. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
	dev->stats.rx_missed_errors += RTL_R32(RxMissed);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
	RTL_W32(RxMissed, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
	spin_unlock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
	synchronize_irq(dev->irq);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
	/* Give a racing hard_start_xmit a few cycles to complete. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
	synchronize_sched();  /* FIXME: should this be synchronize_irq()? */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
	/*
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	 * And now for the 50k$ question: are IRQ disabled or not ?
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
	 *
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	 * Two paths lead here:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	 * 1) dev->close
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
	 *    -> netif_running() is available to sync the current code and the
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	 *       IRQ handler. See rtl8169_interrupt for details.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
	 * 2) dev->change_mtu
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	 *    -> rtl8169_poll can not be issued again and re-enable the
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	 *       interruptions. Let's simply issue the IRQ down sequence again.
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
	 *
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
	 * No loop if hotpluged or major error (0xffff).
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	intrmask = RTL_R16(IntrMask);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
	if (intrmask && (intrmask != 0xffff))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
		goto core_down;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	rtl8169_tx_clear(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	rtl8169_rx_clear(tp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
static int rtl8169_close(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	struct pci_dev *pdev = tp->pci_dev;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	rtl8169_down(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
	free_irq(dev->irq, dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
			    tp->RxPhyAddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
			    tp->TxPhyAddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	tp->TxDescArray = NULL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	tp->RxDescArray = NULL;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
static void rtl_set_rx_mode(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	unsigned long flags;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	u32 mc_filter[2];	/* Multicast hash filter */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
	int rx_mode;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	u32 tmp = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
	if (dev->flags & IFF_PROMISC) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		/* Unconditionally log net taps. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
		if (netif_msg_link(tp)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
			printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
			       dev->name);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
		rx_mode =
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
		    AcceptAllPhys;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
		mc_filter[1] = mc_filter[0] = 0xffffffff;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	} else if ((dev->mc_count > multicast_filter_limit)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
		   || (dev->flags & IFF_ALLMULTI)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
		/* Too many to filter perfectly -- accept all multicasts. */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
		mc_filter[1] = mc_filter[0] = 0xffffffff;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
	} else {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
		struct dev_mc_list *mclist;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
		unsigned int i;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
		rx_mode = AcceptBroadcast | AcceptMyPhys;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
		mc_filter[1] = mc_filter[0] = 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
		     i++, mclist = mclist->next) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
			rx_mode |= AcceptMulticast;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
		}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	spin_lock_irqsave(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
	tmp = rtl8169_rx_config | rx_mode |
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
	      (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
	    (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	    (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	    (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
	    (tp->mac_version == RTL_GIGA_MAC_VER_16) ||
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	    (tp->mac_version == RTL_GIGA_MAC_VER_17)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		mc_filter[0] = 0xffffffff;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
		mc_filter[1] = 0xffffffff;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	RTL_W32(MAR0 + 0, mc_filter[0]);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
	RTL_W32(MAR0 + 4, mc_filter[1]);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
	RTL_W32(RxConfig, tmp);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	spin_unlock_irqrestore(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
/**
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
 *  rtl8169_get_stats - Get rtl8169 read/write statistics
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
 *  @dev: The Ethernet Device to get statistics for
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
 *
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
 *  Get TX/RX statistics for rtl8169
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
 */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
	unsigned long flags;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
	if (netif_running(dev)) {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
		spin_lock_irqsave(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
		dev->stats.rx_missed_errors += RTL_R32(RxMissed);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
		RTL_W32(RxMissed, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
		spin_unlock_irqrestore(&tp->lock, flags);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
	}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	return &dev->stats;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
#ifdef CONFIG_PM
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	struct net_device *dev = pci_get_drvdata(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	struct rtl8169_private *tp = netdev_priv(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	void __iomem *ioaddr = tp->mmio_addr;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	if (!netif_running(dev))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		goto out_pci_suspend;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
	netif_device_detach(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	netif_stop_queue(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
	spin_lock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	rtl8169_asic_down(ioaddr);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
	dev->stats.rx_missed_errors += RTL_R32(RxMissed);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	RTL_W32(RxMissed, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	spin_unlock_irq(&tp->lock);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
out_pci_suspend:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
	pci_save_state(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	pci_enable_wake(pdev, pci_choose_state(pdev, state),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		(tp->features & RTL_FEATURE_WOL) ? 1 : 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
	pci_set_power_state(pdev, pci_choose_state(pdev, state));
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
static int rtl8169_resume(struct pci_dev *pdev)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	struct net_device *dev = pci_get_drvdata(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
	pci_set_power_state(pdev, PCI_D0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
	pci_restore_state(pdev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	pci_enable_wake(pdev, PCI_D0, 0);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	if (!netif_running(dev))
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
		goto out;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
	netif_device_attach(dev);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
	rtl8169_schedule_work(dev, rtl8169_reset_task);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
out:
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	return 0;
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
#endif /* CONFIG_PM */
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
static struct pci_driver rtl8169_pci_driver = {
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	.name		= MODULENAME,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	.id_table	= rtl8169_pci_tbl,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	.probe		= rtl8169_init_one,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	.remove		= __devexit_p(rtl8169_remove_one),
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
#ifdef CONFIG_PM
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	.suspend	= rtl8169_suspend,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	.resume		= rtl8169_resume,
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
#endif
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
};
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
static int __init rtl8169_init_module(void)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	return pci_register_driver(&rtl8169_pci_driver);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
static void __exit rtl8169_cleanup_module(void)
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
{
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	pci_unregister_driver(&rtl8169_pci_driver);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
}
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
module_init(rtl8169_init_module);
22b1de4c74e4 First version of r8169 driver.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
module_exit(rtl8169_cleanup_module);