blob: 86369d7c9a0ff5221a424d44ed20022c3ea9cb44 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* pcnet32.c: An AMD PCnet32 ethernet driver for linux. */
2/*
3 * Copyright 1996-1999 Thomas Bogendoerfer
4 *
5 * Derived from the lance driver written 1993,1994,1995 by Donald Becker.
6 *
7 * Copyright 1993 United States Government as represented by the
8 * Director, National Security Agency.
9 *
10 * This software may be used and distributed according to the terms
11 * of the GNU General Public License, incorporated herein by reference.
12 *
13 * This driver is for PCnet32 and PCnetPCI based ethercards
14 */
15/**************************************************************************
16 * 23 Oct, 2000.
17 * Fixed a few bugs, related to running the controller in 32bit mode.
18 *
19 * Carsten Langgaard, carstenl@mips.com
20 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
21 *
22 *************************************************************************/
23
Joe Perches13ff83b2010-02-15 08:34:25 +000024#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#define DRV_NAME "pcnet32"
Don Fry01935d72008-04-29 13:49:58 -070027#define DRV_VERSION "1.35"
28#define DRV_RELDATE "21.Apr.2008"
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#define PFX DRV_NAME ": "
30
Jeff Garzik4a5e8e22006-03-21 16:15:44 -050031static const char *const version =
32 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " tsbogend@alpha.franken.de\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
34#include <linux/module.h>
35#include <linux/kernel.h>
Alexey Dobriyand43c36d2009-10-07 17:09:06 +040036#include <linux/sched.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/string.h>
38#include <linux/errno.h>
39#include <linux/ioport.h>
40#include <linux/slab.h>
41#include <linux/interrupt.h>
42#include <linux/pci.h>
43#include <linux/delay.h>
44#include <linux/init.h>
45#include <linux/ethtool.h>
46#include <linux/mii.h>
47#include <linux/crc32.h>
48#include <linux/netdevice.h>
49#include <linux/etherdevice.h>
Daniel Drake1f044932009-12-24 08:11:24 +000050#include <linux/if_ether.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include <linux/skbuff.h>
52#include <linux/spinlock.h>
53#include <linux/moduleparam.h>
54#include <linux/bitops.h>
Joe Perches9e3f8062010-02-15 08:34:26 +000055#include <linux/io.h>
56#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
58#include <asm/dma.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070059#include <asm/irq.h>
60
61/*
62 * PCI device identifiers for "new style" Linux PCI Device Drivers
63 */
Benoit Taine9baa3c32014-08-08 15:56:03 +020064static const struct pci_device_id pcnet32_pci_tbl[] = {
Don Fryf2622a22006-06-29 13:52:58 -070065 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME), },
66 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE), },
Jeff Garzik4a5e8e22006-03-21 16:15:44 -050067
68 /*
69 * Adapters that were sold with IBM's RS/6000 or pSeries hardware have
70 * the incorrect vendor id.
71 */
Don Fryf2622a22006-06-29 13:52:58 -070072 { PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_AMD_LANCE),
73 .class = (PCI_CLASS_NETWORK_ETHERNET << 8), .class_mask = 0xffff00, },
Jeff Garzik4a5e8e22006-03-21 16:15:44 -050074
75 { } /* terminate list */
Linus Torvalds1da177e2005-04-16 15:20:36 -070076};
77
Jeff Garzik4a5e8e22006-03-21 16:15:44 -050078MODULE_DEVICE_TABLE(pci, pcnet32_pci_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
80static int cards_found;
81
82/*
83 * VLB I/O addresses
84 */
David S. Miller823dcd22011-08-20 10:39:12 -070085static unsigned int pcnet32_portlist[] =
Jeff Garzik4a5e8e22006-03-21 16:15:44 -050086 { 0x300, 0x320, 0x340, 0x360, 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
Joe Perches9e3f8062010-02-15 08:34:26 +000088static int pcnet32_debug;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -050089static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */
90static int pcnet32vlb; /* check for VLB cards ? */
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
92static struct net_device *pcnet32_dev;
93
94static int max_interrupt_work = 2;
95static int rx_copybreak = 200;
96
97#define PCNET32_PORT_AUI 0x00
98#define PCNET32_PORT_10BT 0x01
99#define PCNET32_PORT_GPSI 0x02
100#define PCNET32_PORT_MII 0x03
101
102#define PCNET32_PORT_PORTSEL 0x03
103#define PCNET32_PORT_ASEL 0x04
104#define PCNET32_PORT_100 0x40
105#define PCNET32_PORT_FD 0x80
106
107#define PCNET32_DMA_MASK 0xffffffff
108
109#define PCNET32_WATCHDOG_TIMEOUT (jiffies + (2 * HZ))
110#define PCNET32_BLINK_TIMEOUT (jiffies + (HZ/4))
111
112/*
113 * table to translate option values from tulip
114 * to internal options
115 */
Arjan van de Venf71e1302006-03-03 21:33:57 -0500116static const unsigned char options_mapping[] = {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500117 PCNET32_PORT_ASEL, /* 0 Auto-select */
118 PCNET32_PORT_AUI, /* 1 BNC/AUI */
119 PCNET32_PORT_AUI, /* 2 AUI/BNC */
120 PCNET32_PORT_ASEL, /* 3 not supported */
121 PCNET32_PORT_10BT | PCNET32_PORT_FD, /* 4 10baseT-FD */
122 PCNET32_PORT_ASEL, /* 5 not supported */
123 PCNET32_PORT_ASEL, /* 6 not supported */
124 PCNET32_PORT_ASEL, /* 7 not supported */
125 PCNET32_PORT_ASEL, /* 8 not supported */
126 PCNET32_PORT_MII, /* 9 MII 10baseT */
127 PCNET32_PORT_MII | PCNET32_PORT_FD, /* 10 MII 10baseT-FD */
128 PCNET32_PORT_MII, /* 11 MII (autosel) */
129 PCNET32_PORT_10BT, /* 12 10BaseT */
130 PCNET32_PORT_MII | PCNET32_PORT_100, /* 13 MII 100BaseTx */
131 /* 14 MII 100BaseTx-FD */
132 PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD,
133 PCNET32_PORT_ASEL /* 15 not supported */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134};
135
136static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] = {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500137 "Loopback test (offline)"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138};
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500139
Alejandro Martinez Ruiz4c3616c2007-10-18 10:00:15 +0200140#define PCNET32_TEST_LEN ARRAY_SIZE(pcnet32_gstrings_test)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
Don Fryac62ef02006-03-20 15:26:03 -0800142#define PCNET32_NUM_REGS 136
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500144#define MAX_UNITS 8 /* More are supported, limit only on options */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145static int options[MAX_UNITS];
146static int full_duplex[MAX_UNITS];
147static int homepna[MAX_UNITS];
148
149/*
150 * Theory of Operation
151 *
152 * This driver uses the same software structure as the normal lance
153 * driver. So look for a verbose description in lance.c. The differences
154 * to the normal lance driver is the use of the 32bit mode of PCnet32
155 * and PCnetPCI chips. Because these chips are 32bit chips, there is no
156 * 16MB limitation and we don't need bounce buffers.
157 */
158
159/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 * Set the number of Tx and Rx buffers, using Log_2(# buffers).
161 * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
162 * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
163 */
164#ifndef PCNET32_LOG_TX_BUFFERS
Hubert WS Lineabf0412005-09-14 11:39:25 -0700165#define PCNET32_LOG_TX_BUFFERS 4
166#define PCNET32_LOG_RX_BUFFERS 5
167#define PCNET32_LOG_MAX_TX_BUFFERS 9 /* 2^9 == 512 */
168#define PCNET32_LOG_MAX_RX_BUFFERS 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169#endif
170
171#define TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS))
Hubert WS Lineabf0412005-09-14 11:39:25 -0700172#define TX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_TX_BUFFERS))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
174#define RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS))
Hubert WS Lineabf0412005-09-14 11:39:25 -0700175#define RX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_RX_BUFFERS))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176
Don Fry232c5642008-02-08 07:32:26 -0800177#define PKT_BUF_SKB 1544
178/* actual buffer length after being aligned */
179#define PKT_BUF_SIZE (PKT_BUF_SKB - NET_IP_ALIGN)
180/* chip wants twos complement of the (aligned) buffer length */
181#define NEG_BUF_SIZE (NET_IP_ALIGN - PKT_BUF_SKB)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182
183/* Offsets from base I/O address. */
184#define PCNET32_WIO_RDP 0x10
185#define PCNET32_WIO_RAP 0x12
186#define PCNET32_WIO_RESET 0x14
187#define PCNET32_WIO_BDP 0x16
188
189#define PCNET32_DWIO_RDP 0x10
190#define PCNET32_DWIO_RAP 0x14
191#define PCNET32_DWIO_RESET 0x18
192#define PCNET32_DWIO_BDP 0x1C
193
194#define PCNET32_TOTAL_SIZE 0x20
195
Don Fry06c87852006-06-29 13:54:38 -0700196#define CSR0 0
197#define CSR0_INIT 0x1
198#define CSR0_START 0x2
199#define CSR0_STOP 0x4
200#define CSR0_TXPOLL 0x8
201#define CSR0_INTEN 0x40
202#define CSR0_IDON 0x0100
203#define CSR0_NORMAL (CSR0_START | CSR0_INTEN)
204#define PCNET32_INIT_LOW 1
205#define PCNET32_INIT_HIGH 2
206#define CSR3 3
207#define CSR4 4
208#define CSR5 5
209#define CSR5_SUSPEND 0x0001
210#define CSR15 15
211#define PCNET32_MC_FILTER 8
212
Don Fry8d916262006-08-22 10:22:37 -0700213#define PCNET32_79C970A 0x2621
214
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215/* The PCNET32 Rx and Tx ring descriptors. */
216struct pcnet32_rx_head {
Al Viro3e335452007-08-23 00:45:46 -0400217 __le32 base;
218 __le16 buf_length; /* two`s complement of length */
219 __le16 status;
220 __le32 msg_length;
221 __le32 reserved;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222};
223
224struct pcnet32_tx_head {
Al Viro3e335452007-08-23 00:45:46 -0400225 __le32 base;
226 __le16 length; /* two`s complement of length */
227 __le16 status;
228 __le32 misc;
229 __le32 reserved;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230};
231
232/* The PCNET32 32-Bit initialization block, described in databook. */
233struct pcnet32_init_block {
Al Viro3e335452007-08-23 00:45:46 -0400234 __le16 mode;
235 __le16 tlen_rlen;
Jeff Garzik0b5bf222006-03-21 16:22:47 -0500236 u8 phys_addr[6];
Al Viro3e335452007-08-23 00:45:46 -0400237 __le16 reserved;
238 __le32 filter[2];
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500239 /* Receive and transmit ring base, along with extra bits. */
Al Viro3e335452007-08-23 00:45:46 -0400240 __le32 rx_ring;
241 __le32 tx_ring;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242};
243
244/* PCnet32 access functions */
245struct pcnet32_access {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500246 u16 (*read_csr) (unsigned long, int);
247 void (*write_csr) (unsigned long, int, u16);
248 u16 (*read_bcr) (unsigned long, int);
249 void (*write_bcr) (unsigned long, int, u16);
250 u16 (*read_rap) (unsigned long);
251 void (*write_rap) (unsigned long, u16);
252 void (*reset) (unsigned long);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253};
254
255/*
Hubert WS Lin76209922005-09-14 11:39:27 -0700256 * The first field of pcnet32_private is read by the ethernet device
257 * so the structure should be allocated using pci_alloc_consistent().
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 */
259struct pcnet32_private {
Don Fry6ecb7662007-03-06 10:45:23 -0800260 struct pcnet32_init_block *init_block;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500261 /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
Jeff Garzik0b5bf222006-03-21 16:22:47 -0500262 struct pcnet32_rx_head *rx_ring;
263 struct pcnet32_tx_head *tx_ring;
Don Fry6ecb7662007-03-06 10:45:23 -0800264 dma_addr_t init_dma_addr;/* DMA address of beginning of the init block,
265 returned by pci_alloc_consistent */
Jeff Garzik0b5bf222006-03-21 16:22:47 -0500266 struct pci_dev *pci_dev;
267 const char *name;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500268 /* The saved address of a sent-in-place packet/buffer, for skfree(). */
Jeff Garzik0b5bf222006-03-21 16:22:47 -0500269 struct sk_buff **tx_skbuff;
270 struct sk_buff **rx_skbuff;
271 dma_addr_t *tx_dma_addr;
272 dma_addr_t *rx_dma_addr;
stephen hemminger1d70cb02011-09-16 11:06:26 +0000273 const struct pcnet32_access *a;
Jeff Garzik0b5bf222006-03-21 16:22:47 -0500274 spinlock_t lock; /* Guard lock */
275 unsigned int cur_rx, cur_tx; /* The next free ring entry */
276 unsigned int rx_ring_size; /* current rx ring size */
277 unsigned int tx_ring_size; /* current tx ring size */
278 unsigned int rx_mod_mask; /* rx ring modular mask */
279 unsigned int tx_mod_mask; /* tx ring modular mask */
280 unsigned short rx_len_bits;
281 unsigned short tx_len_bits;
282 dma_addr_t rx_ring_dma_addr;
283 dma_addr_t tx_ring_dma_addr;
284 unsigned int dirty_rx, /* ring entries to be freed. */
285 dirty_tx;
286
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700287 struct net_device *dev;
288 struct napi_struct napi;
Jeff Garzik0b5bf222006-03-21 16:22:47 -0500289 char tx_full;
290 char phycount; /* number of phys found */
291 int options;
292 unsigned int shared_irq:1, /* shared irq possible */
293 dxsuflo:1, /* disable transmit stop on uflo */
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100294 mii:1, /* mii port available */
295 autoneg:1, /* autoneg enabled */
296 port_tp:1, /* port set to TP */
297 fdx:1; /* full duplex enabled */
Jeff Garzik0b5bf222006-03-21 16:22:47 -0500298 struct net_device *next;
299 struct mii_if_info mii_if;
300 struct timer_list watchdog_timer;
Jeff Garzik0b5bf222006-03-21 16:22:47 -0500301 u32 msg_enable; /* debug message level */
Don Fryac62ef02006-03-20 15:26:03 -0800302
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500303 /* each bit indicates an available PHY */
Jeff Garzik0b5bf222006-03-21 16:22:47 -0500304 u32 phymask;
Don Fry8d916262006-08-22 10:22:37 -0700305 unsigned short chip_version; /* which variant this is */
stephen hemminger9871acf2011-04-04 11:06:41 +0000306
307 /* saved registers during ethtool blink */
308 u16 save_regs[4];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309};
310
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500311static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
312static int pcnet32_probe1(unsigned long, int, struct pci_dev *);
313static int pcnet32_open(struct net_device *);
314static int pcnet32_init_ring(struct net_device *);
Stephen Hemminger613573252009-08-31 19:50:58 +0000315static netdev_tx_t pcnet32_start_xmit(struct sk_buff *,
316 struct net_device *);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500317static void pcnet32_tx_timeout(struct net_device *dev);
David Howells7d12e782006-10-05 14:55:46 +0100318static irqreturn_t pcnet32_interrupt(int, void *);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500319static int pcnet32_close(struct net_device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320static struct net_device_stats *pcnet32_get_stats(struct net_device *);
321static void pcnet32_load_multicast(struct net_device *dev);
322static void pcnet32_set_multicast_list(struct net_device *);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500323static int pcnet32_ioctl(struct net_device *, struct ifreq *, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324static void pcnet32_watchdog(struct net_device *);
325static int mdio_read(struct net_device *dev, int phy_id, int reg_num);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500326static void mdio_write(struct net_device *dev, int phy_id, int reg_num,
327 int val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits);
329static void pcnet32_ethtool_test(struct net_device *dev,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500330 struct ethtool_test *eth_test, u64 * data);
331static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332static int pcnet32_get_regs_len(struct net_device *dev);
333static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500334 void *ptr);
Don Fry1bcd3152005-04-29 14:51:17 -0700335static void pcnet32_purge_tx_ring(struct net_device *dev);
Andrew Mortonb166cfb2008-05-14 16:20:14 -0700336static int pcnet32_alloc_ring(struct net_device *dev, const char *name);
Hubert WS Lineabf0412005-09-14 11:39:25 -0700337static void pcnet32_free_ring(struct net_device *dev);
Don Fryac62ef02006-03-20 15:26:03 -0800338static void pcnet32_check_media(struct net_device *dev, int verbose);
Hubert WS Lineabf0412005-09-14 11:39:25 -0700339
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500340static u16 pcnet32_wio_read_csr(unsigned long addr, int index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500342 outw(index, addr + PCNET32_WIO_RAP);
343 return inw(addr + PCNET32_WIO_RDP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344}
345
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500346static void pcnet32_wio_write_csr(unsigned long addr, int index, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500348 outw(index, addr + PCNET32_WIO_RAP);
349 outw(val, addr + PCNET32_WIO_RDP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350}
351
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500352static u16 pcnet32_wio_read_bcr(unsigned long addr, int index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500354 outw(index, addr + PCNET32_WIO_RAP);
355 return inw(addr + PCNET32_WIO_BDP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356}
357
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500358static void pcnet32_wio_write_bcr(unsigned long addr, int index, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500360 outw(index, addr + PCNET32_WIO_RAP);
361 outw(val, addr + PCNET32_WIO_BDP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362}
363
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500364static u16 pcnet32_wio_read_rap(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500366 return inw(addr + PCNET32_WIO_RAP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367}
368
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500369static void pcnet32_wio_write_rap(unsigned long addr, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500371 outw(val, addr + PCNET32_WIO_RAP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372}
373
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500374static void pcnet32_wio_reset(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500376 inw(addr + PCNET32_WIO_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377}
378
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500379static int pcnet32_wio_check(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500381 outw(88, addr + PCNET32_WIO_RAP);
Eric Dumazet807540b2010-09-23 05:40:09 +0000382 return inw(addr + PCNET32_WIO_RAP) == 88;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383}
384
stephen hemminger1d70cb02011-09-16 11:06:26 +0000385static const struct pcnet32_access pcnet32_wio = {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500386 .read_csr = pcnet32_wio_read_csr,
387 .write_csr = pcnet32_wio_write_csr,
388 .read_bcr = pcnet32_wio_read_bcr,
389 .write_bcr = pcnet32_wio_write_bcr,
390 .read_rap = pcnet32_wio_read_rap,
391 .write_rap = pcnet32_wio_write_rap,
392 .reset = pcnet32_wio_reset
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393};
394
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500395static u16 pcnet32_dwio_read_csr(unsigned long addr, int index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500397 outl(index, addr + PCNET32_DWIO_RAP);
Joe Perches9e3f8062010-02-15 08:34:26 +0000398 return inl(addr + PCNET32_DWIO_RDP) & 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399}
400
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500401static void pcnet32_dwio_write_csr(unsigned long addr, int index, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500403 outl(index, addr + PCNET32_DWIO_RAP);
404 outl(val, addr + PCNET32_DWIO_RDP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405}
406
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500407static u16 pcnet32_dwio_read_bcr(unsigned long addr, int index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500409 outl(index, addr + PCNET32_DWIO_RAP);
Joe Perches9e3f8062010-02-15 08:34:26 +0000410 return inl(addr + PCNET32_DWIO_BDP) & 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411}
412
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500413static void pcnet32_dwio_write_bcr(unsigned long addr, int index, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500415 outl(index, addr + PCNET32_DWIO_RAP);
416 outl(val, addr + PCNET32_DWIO_BDP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417}
418
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500419static u16 pcnet32_dwio_read_rap(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420{
Joe Perches9e3f8062010-02-15 08:34:26 +0000421 return inl(addr + PCNET32_DWIO_RAP) & 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422}
423
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500424static void pcnet32_dwio_write_rap(unsigned long addr, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500426 outl(val, addr + PCNET32_DWIO_RAP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427}
428
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500429static void pcnet32_dwio_reset(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500431 inl(addr + PCNET32_DWIO_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432}
433
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500434static int pcnet32_dwio_check(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500436 outl(88, addr + PCNET32_DWIO_RAP);
Eric Dumazet807540b2010-09-23 05:40:09 +0000437 return (inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438}
439
stephen hemminger1d70cb02011-09-16 11:06:26 +0000440static const struct pcnet32_access pcnet32_dwio = {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500441 .read_csr = pcnet32_dwio_read_csr,
442 .write_csr = pcnet32_dwio_write_csr,
443 .read_bcr = pcnet32_dwio_read_bcr,
444 .write_bcr = pcnet32_dwio_write_bcr,
445 .read_rap = pcnet32_dwio_read_rap,
446 .write_rap = pcnet32_dwio_write_rap,
447 .reset = pcnet32_dwio_reset
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448};
449
Don Fry06c87852006-06-29 13:54:38 -0700450static void pcnet32_netif_stop(struct net_device *dev)
451{
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700452 struct pcnet32_private *lp = netdev_priv(dev);
Don Fry01935d72008-04-29 13:49:58 -0700453
Florian Westphal860e9532016-05-03 16:33:13 +0200454 netif_trans_update(dev); /* prevent tx timeout */
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700455 napi_disable(&lp->napi);
Don Fry06c87852006-06-29 13:54:38 -0700456 netif_tx_disable(dev);
457}
458
459static void pcnet32_netif_start(struct net_device *dev)
460{
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700461 struct pcnet32_private *lp = netdev_priv(dev);
David S. Millerd1d08d12008-01-07 20:53:33 -0800462 ulong ioaddr = dev->base_addr;
463 u16 val;
Don Fry01935d72008-04-29 13:49:58 -0700464
Don Fry06c87852006-06-29 13:54:38 -0700465 netif_wake_queue(dev);
stephen hemminger1d70cb02011-09-16 11:06:26 +0000466 val = lp->a->read_csr(ioaddr, CSR3);
David S. Millerd1d08d12008-01-07 20:53:33 -0800467 val &= 0x00ff;
stephen hemminger1d70cb02011-09-16 11:06:26 +0000468 lp->a->write_csr(ioaddr, CSR3, val);
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700469 napi_enable(&lp->napi);
Don Fry06c87852006-06-29 13:54:38 -0700470}
471
472/*
473 * Allocate space for the new sized tx ring.
474 * Free old resources
475 * Save new resources.
476 * Any failure keeps old resources.
477 * Must be called with lp->lock held.
478 */
479static void pcnet32_realloc_tx_ring(struct net_device *dev,
480 struct pcnet32_private *lp,
481 unsigned int size)
482{
483 dma_addr_t new_ring_dma_addr;
484 dma_addr_t *new_dma_addr_list;
485 struct pcnet32_tx_head *new_tx_ring;
486 struct sk_buff **new_skb_list;
Joe Perchese03aec12014-08-08 14:24:55 -0700487 unsigned int entries = BIT(size);
Don Fry06c87852006-06-29 13:54:38 -0700488
489 pcnet32_purge_tx_ring(dev);
490
Joe Perchese03aec12014-08-08 14:24:55 -0700491 new_tx_ring =
492 pci_zalloc_consistent(lp->pci_dev,
493 sizeof(struct pcnet32_tx_head) * entries,
494 &new_ring_dma_addr);
495 if (new_tx_ring == NULL)
Don Fry06c87852006-06-29 13:54:38 -0700496 return;
Don Fry06c87852006-06-29 13:54:38 -0700497
Joe Perchese03aec12014-08-08 14:24:55 -0700498 new_dma_addr_list = kcalloc(entries, sizeof(dma_addr_t), GFP_ATOMIC);
Joe Perches14f8dc42013-02-07 11:46:27 +0000499 if (!new_dma_addr_list)
Don Fry06c87852006-06-29 13:54:38 -0700500 goto free_new_tx_ring;
Don Fry06c87852006-06-29 13:54:38 -0700501
Joe Perchese03aec12014-08-08 14:24:55 -0700502 new_skb_list = kcalloc(entries, sizeof(struct sk_buff *), GFP_ATOMIC);
Joe Perches14f8dc42013-02-07 11:46:27 +0000503 if (!new_skb_list)
Don Fry06c87852006-06-29 13:54:38 -0700504 goto free_new_lists;
Don Fry06c87852006-06-29 13:54:38 -0700505
506 kfree(lp->tx_skbuff);
507 kfree(lp->tx_dma_addr);
508 pci_free_consistent(lp->pci_dev,
Joe Perchese03aec12014-08-08 14:24:55 -0700509 sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
510 lp->tx_ring, lp->tx_ring_dma_addr);
Don Fry06c87852006-06-29 13:54:38 -0700511
Joe Perchese03aec12014-08-08 14:24:55 -0700512 lp->tx_ring_size = entries;
Don Fry06c87852006-06-29 13:54:38 -0700513 lp->tx_mod_mask = lp->tx_ring_size - 1;
514 lp->tx_len_bits = (size << 12);
515 lp->tx_ring = new_tx_ring;
516 lp->tx_ring_dma_addr = new_ring_dma_addr;
517 lp->tx_dma_addr = new_dma_addr_list;
518 lp->tx_skbuff = new_skb_list;
519 return;
520
Joe Perches9e3f8062010-02-15 08:34:26 +0000521free_new_lists:
Don Fry06c87852006-06-29 13:54:38 -0700522 kfree(new_dma_addr_list);
Joe Perches9e3f8062010-02-15 08:34:26 +0000523free_new_tx_ring:
Don Fry06c87852006-06-29 13:54:38 -0700524 pci_free_consistent(lp->pci_dev,
Joe Perchese03aec12014-08-08 14:24:55 -0700525 sizeof(struct pcnet32_tx_head) * entries,
Don Fry06c87852006-06-29 13:54:38 -0700526 new_tx_ring,
527 new_ring_dma_addr);
Don Fry06c87852006-06-29 13:54:38 -0700528}
529
530/*
531 * Allocate space for the new sized rx ring.
532 * Re-use old receive buffers.
533 * alloc extra buffers
534 * free unneeded buffers
535 * free unneeded buffers
536 * Save new resources.
537 * Any failure keeps old resources.
538 * Must be called with lp->lock held.
539 */
540static void pcnet32_realloc_rx_ring(struct net_device *dev,
541 struct pcnet32_private *lp,
542 unsigned int size)
543{
544 dma_addr_t new_ring_dma_addr;
545 dma_addr_t *new_dma_addr_list;
546 struct pcnet32_rx_head *new_rx_ring;
547 struct sk_buff **new_skb_list;
548 int new, overlap;
Joe Perchese03aec12014-08-08 14:24:55 -0700549 unsigned int entries = BIT(size);
Don Fry06c87852006-06-29 13:54:38 -0700550
Joe Perchese03aec12014-08-08 14:24:55 -0700551 new_rx_ring =
552 pci_zalloc_consistent(lp->pci_dev,
553 sizeof(struct pcnet32_rx_head) * entries,
554 &new_ring_dma_addr);
555 if (new_rx_ring == NULL)
Don Fry06c87852006-06-29 13:54:38 -0700556 return;
Don Fry06c87852006-06-29 13:54:38 -0700557
Don Fry60e2e8b2014-02-17 20:57:46 -0800558 new_dma_addr_list = kcalloc(entries, sizeof(dma_addr_t), GFP_ATOMIC);
Joe Perches14f8dc42013-02-07 11:46:27 +0000559 if (!new_dma_addr_list)
Don Fry06c87852006-06-29 13:54:38 -0700560 goto free_new_rx_ring;
Don Fry06c87852006-06-29 13:54:38 -0700561
Don Fry4cc5c472014-02-17 20:57:59 -0800562 new_skb_list = kcalloc(entries, sizeof(struct sk_buff *), GFP_ATOMIC);
Joe Perches14f8dc42013-02-07 11:46:27 +0000563 if (!new_skb_list)
Don Fry06c87852006-06-29 13:54:38 -0700564 goto free_new_lists;
Don Fry06c87852006-06-29 13:54:38 -0700565
566 /* first copy the current receive buffers */
Don Fry60e2e8b2014-02-17 20:57:46 -0800567 overlap = min(entries, lp->rx_ring_size);
Don Fry06c87852006-06-29 13:54:38 -0700568 for (new = 0; new < overlap; new++) {
569 new_rx_ring[new] = lp->rx_ring[new];
570 new_dma_addr_list[new] = lp->rx_dma_addr[new];
571 new_skb_list[new] = lp->rx_skbuff[new];
572 }
573 /* now allocate any new buffers needed */
Don Fry60e2e8b2014-02-17 20:57:46 -0800574 for (; new < entries; new++) {
Don Fry06c87852006-06-29 13:54:38 -0700575 struct sk_buff *rx_skbuff;
Pradeep A Dalvi1d266432012-02-05 02:49:09 +0000576 new_skb_list[new] = netdev_alloc_skb(dev, PKT_BUF_SKB);
Joe Perches9e3f8062010-02-15 08:34:26 +0000577 rx_skbuff = new_skb_list[new];
578 if (!rx_skbuff) {
Don Fry06c87852006-06-29 13:54:38 -0700579 /* keep the original lists and buffers */
Pradeep A Dalvi1d266432012-02-05 02:49:09 +0000580 netif_err(lp, drv, dev, "%s netdev_alloc_skb failed\n",
Joe Perches13ff83b2010-02-15 08:34:25 +0000581 __func__);
Don Fry06c87852006-06-29 13:54:38 -0700582 goto free_all_new;
583 }
Don Fry232c5642008-02-08 07:32:26 -0800584 skb_reserve(rx_skbuff, NET_IP_ALIGN);
Don Fry06c87852006-06-29 13:54:38 -0700585
586 new_dma_addr_list[new] =
587 pci_map_single(lp->pci_dev, rx_skbuff->data,
Don Fry232c5642008-02-08 07:32:26 -0800588 PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
Don Fry4cc5c472014-02-17 20:57:59 -0800589 if (pci_dma_mapping_error(lp->pci_dev,
590 new_dma_addr_list[new])) {
591 netif_err(lp, drv, dev, "%s dma mapping failed\n",
592 __func__);
593 dev_kfree_skb(new_skb_list[new]);
594 goto free_all_new;
595 }
Al Viro3e335452007-08-23 00:45:46 -0400596 new_rx_ring[new].base = cpu_to_le32(new_dma_addr_list[new]);
Don Fry232c5642008-02-08 07:32:26 -0800597 new_rx_ring[new].buf_length = cpu_to_le16(NEG_BUF_SIZE);
Al Viro3e335452007-08-23 00:45:46 -0400598 new_rx_ring[new].status = cpu_to_le16(0x8000);
Don Fry06c87852006-06-29 13:54:38 -0700599 }
600 /* and free any unneeded buffers */
601 for (; new < lp->rx_ring_size; new++) {
602 if (lp->rx_skbuff[new]) {
Don Fry4cc5c472014-02-17 20:57:59 -0800603 if (!pci_dma_mapping_error(lp->pci_dev,
604 lp->rx_dma_addr[new]))
605 pci_unmap_single(lp->pci_dev,
606 lp->rx_dma_addr[new],
607 PKT_BUF_SIZE,
608 PCI_DMA_FROMDEVICE);
Don Fry06c87852006-06-29 13:54:38 -0700609 dev_kfree_skb(lp->rx_skbuff[new]);
610 }
611 }
612
613 kfree(lp->rx_skbuff);
614 kfree(lp->rx_dma_addr);
615 pci_free_consistent(lp->pci_dev,
616 sizeof(struct pcnet32_rx_head) *
617 lp->rx_ring_size, lp->rx_ring,
618 lp->rx_ring_dma_addr);
619
Don Fry60e2e8b2014-02-17 20:57:46 -0800620 lp->rx_ring_size = entries;
Don Fry06c87852006-06-29 13:54:38 -0700621 lp->rx_mod_mask = lp->rx_ring_size - 1;
622 lp->rx_len_bits = (size << 4);
623 lp->rx_ring = new_rx_ring;
624 lp->rx_ring_dma_addr = new_ring_dma_addr;
625 lp->rx_dma_addr = new_dma_addr_list;
626 lp->rx_skbuff = new_skb_list;
627 return;
628
Joe Perches9e3f8062010-02-15 08:34:26 +0000629free_all_new:
630 while (--new >= lp->rx_ring_size) {
Don Fry06c87852006-06-29 13:54:38 -0700631 if (new_skb_list[new]) {
Don Fry4cc5c472014-02-17 20:57:59 -0800632 if (!pci_dma_mapping_error(lp->pci_dev,
633 new_dma_addr_list[new]))
634 pci_unmap_single(lp->pci_dev,
635 new_dma_addr_list[new],
636 PKT_BUF_SIZE,
637 PCI_DMA_FROMDEVICE);
Don Fry06c87852006-06-29 13:54:38 -0700638 dev_kfree_skb(new_skb_list[new]);
639 }
640 }
641 kfree(new_skb_list);
Joe Perches9e3f8062010-02-15 08:34:26 +0000642free_new_lists:
Don Fry06c87852006-06-29 13:54:38 -0700643 kfree(new_dma_addr_list);
Joe Perches9e3f8062010-02-15 08:34:26 +0000644free_new_rx_ring:
Don Fry06c87852006-06-29 13:54:38 -0700645 pci_free_consistent(lp->pci_dev,
Don Fry60e2e8b2014-02-17 20:57:46 -0800646 sizeof(struct pcnet32_rx_head) * entries,
Don Fry06c87852006-06-29 13:54:38 -0700647 new_rx_ring,
648 new_ring_dma_addr);
Don Fry06c87852006-06-29 13:54:38 -0700649}
650
Don Fryac5bfe42006-06-29 13:55:27 -0700651static void pcnet32_purge_rx_ring(struct net_device *dev)
652{
Don Fry1e56a4b2007-03-06 10:55:00 -0800653 struct pcnet32_private *lp = netdev_priv(dev);
Don Fryac5bfe42006-06-29 13:55:27 -0700654 int i;
655
656 /* free all allocated skbuffs */
657 for (i = 0; i < lp->rx_ring_size; i++) {
658 lp->rx_ring[i].status = 0; /* CPU owns buffer */
659 wmb(); /* Make sure adapter sees owner change */
660 if (lp->rx_skbuff[i]) {
Don Fry4cc5c472014-02-17 20:57:59 -0800661 if (!pci_dma_mapping_error(lp->pci_dev,
662 lp->rx_dma_addr[i]))
663 pci_unmap_single(lp->pci_dev,
664 lp->rx_dma_addr[i],
665 PKT_BUF_SIZE,
666 PCI_DMA_FROMDEVICE);
Don Fryac5bfe42006-06-29 13:55:27 -0700667 dev_kfree_skb_any(lp->rx_skbuff[i]);
668 }
669 lp->rx_skbuff[i] = NULL;
670 lp->rx_dma_addr[i] = 0;
671 }
672}
673
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674#ifdef CONFIG_NET_POLL_CONTROLLER
675static void pcnet32_poll_controller(struct net_device *dev)
676{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500677 disable_irq(dev->irq);
David Howells7d12e782006-10-05 14:55:46 +0100678 pcnet32_interrupt(0, dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500679 enable_irq(dev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680}
681#endif
682
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100683/*
684 * lp->lock must be held.
685 */
686static int pcnet32_suspend(struct net_device *dev, unsigned long *flags,
687 int can_sleep)
688{
689 int csr5;
690 struct pcnet32_private *lp = netdev_priv(dev);
691 const struct pcnet32_access *a = lp->a;
692 ulong ioaddr = dev->base_addr;
693 int ticks;
694
695 /* really old chips have to be stopped. */
696 if (lp->chip_version < PCNET32_79C970A)
697 return 0;
698
699 /* set SUSPEND (SPND) - CSR5 bit 0 */
700 csr5 = a->read_csr(ioaddr, CSR5);
701 a->write_csr(ioaddr, CSR5, csr5 | CSR5_SUSPEND);
702
703 /* poll waiting for bit to be set */
704 ticks = 0;
705 while (!(a->read_csr(ioaddr, CSR5) & CSR5_SUSPEND)) {
706 spin_unlock_irqrestore(&lp->lock, *flags);
707 if (can_sleep)
708 msleep(1);
709 else
710 mdelay(1);
711 spin_lock_irqsave(&lp->lock, *flags);
712 ticks++;
713 if (ticks > 200) {
714 netif_printk(lp, hw, KERN_DEBUG, dev,
715 "Error getting into suspend!\n");
716 return 0;
717 }
718 }
719 return 1;
720}
721
722static void pcnet32_clr_suspend(struct pcnet32_private *lp, ulong ioaddr)
723{
724 int csr5 = lp->a->read_csr(ioaddr, CSR5);
725 /* clear SUSPEND (SPND) - CSR5 bit 0 */
726 lp->a->write_csr(ioaddr, CSR5, csr5 & ~CSR5_SUSPEND);
727}
728
Philippe Reynesea74df82016-11-06 00:26:41 +0100729static int pcnet32_get_link_ksettings(struct net_device *dev,
730 struct ethtool_link_ksettings *cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731{
Don Fry1e56a4b2007-03-06 10:55:00 -0800732 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500733 unsigned long flags;
734 int r = -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100736 spin_lock_irqsave(&lp->lock, flags);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500737 if (lp->mii) {
Philippe Reynesea74df82016-11-06 00:26:41 +0100738 mii_ethtool_get_link_ksettings(&lp->mii_if, cmd);
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100739 r = 0;
740 } else if (lp->chip_version == PCNET32_79C970A) {
741 if (lp->autoneg) {
742 cmd->base.autoneg = AUTONEG_ENABLE;
743 if (lp->a->read_bcr(dev->base_addr, 4) == 0xc0)
744 cmd->base.port = PORT_AUI;
745 else
746 cmd->base.port = PORT_TP;
747 } else {
748 cmd->base.autoneg = AUTONEG_DISABLE;
749 cmd->base.port = lp->port_tp ? PORT_TP : PORT_AUI;
750 }
751 cmd->base.duplex = lp->fdx ? DUPLEX_FULL : DUPLEX_HALF;
752 cmd->base.speed = SPEED_10;
753 ethtool_convert_legacy_u32_to_link_mode(
754 cmd->link_modes.supported,
755 SUPPORTED_TP | SUPPORTED_AUI);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500756 r = 0;
757 }
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100758 spin_unlock_irqrestore(&lp->lock, flags);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500759 return r;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760}
761
Philippe Reynesea74df82016-11-06 00:26:41 +0100762static int pcnet32_set_link_ksettings(struct net_device *dev,
763 const struct ethtool_link_ksettings *cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764{
Don Fry1e56a4b2007-03-06 10:55:00 -0800765 struct pcnet32_private *lp = netdev_priv(dev);
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100766 ulong ioaddr = dev->base_addr;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500767 unsigned long flags;
768 int r = -EOPNOTSUPP;
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100769 int suspended, bcr2, bcr9, csr15;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100771 spin_lock_irqsave(&lp->lock, flags);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500772 if (lp->mii) {
Philippe Reynesea74df82016-11-06 00:26:41 +0100773 r = mii_ethtool_set_link_ksettings(&lp->mii_if, cmd);
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100774 } else if (lp->chip_version == PCNET32_79C970A) {
775 suspended = pcnet32_suspend(dev, &flags, 0);
776 if (!suspended)
777 lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
778
779 lp->autoneg = cmd->base.autoneg == AUTONEG_ENABLE;
780 bcr2 = lp->a->read_bcr(ioaddr, 2);
781 if (cmd->base.autoneg == AUTONEG_ENABLE) {
782 lp->a->write_bcr(ioaddr, 2, bcr2 | 0x0002);
783 } else {
784 lp->a->write_bcr(ioaddr, 2, bcr2 & ~0x0002);
785
786 lp->port_tp = cmd->base.port == PORT_TP;
787 csr15 = lp->a->read_csr(ioaddr, CSR15) & ~0x0180;
788 if (cmd->base.port == PORT_TP)
789 csr15 |= 0x0080;
790 lp->a->write_csr(ioaddr, CSR15, csr15);
791 lp->init_block->mode = cpu_to_le16(csr15);
792
793 lp->fdx = cmd->base.duplex == DUPLEX_FULL;
794 bcr9 = lp->a->read_bcr(ioaddr, 9) & ~0x0003;
795 if (cmd->base.duplex == DUPLEX_FULL)
796 bcr9 |= 0x0003;
797 lp->a->write_bcr(ioaddr, 9, bcr9);
798 }
799 if (suspended)
800 pcnet32_clr_suspend(lp, ioaddr);
801 else if (netif_running(dev))
802 pcnet32_restart(dev, CSR0_NORMAL);
803 r = 0;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500804 }
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100805 spin_unlock_irqrestore(&lp->lock, flags);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500806 return r;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807}
808
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500809static void pcnet32_get_drvinfo(struct net_device *dev,
810 struct ethtool_drvinfo *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811{
Don Fry1e56a4b2007-03-06 10:55:00 -0800812 struct pcnet32_private *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
Rick Jones23020ab2011-11-09 09:58:07 +0000814 strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
815 strlcpy(info->version, DRV_VERSION, sizeof(info->version));
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500816 if (lp->pci_dev)
Rick Jones23020ab2011-11-09 09:58:07 +0000817 strlcpy(info->bus_info, pci_name(lp->pci_dev),
818 sizeof(info->bus_info));
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500819 else
Rick Jones23020ab2011-11-09 09:58:07 +0000820 snprintf(info->bus_info, sizeof(info->bus_info),
821 "VLB 0x%lx", dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822}
823
824static u32 pcnet32_get_link(struct net_device *dev)
825{
Don Fry1e56a4b2007-03-06 10:55:00 -0800826 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500827 unsigned long flags;
828 int r;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500830 spin_lock_irqsave(&lp->lock, flags);
831 if (lp->mii) {
832 r = mii_link_ok(&lp->mii_if);
Ondrej Zary2be4cb92017-02-13 23:45:47 +0100833 } else if (lp->chip_version == PCNET32_79C970A) {
834 ulong ioaddr = dev->base_addr; /* card base I/O address */
835 /* only read link if port is set to TP */
836 if (!lp->autoneg && lp->port_tp)
837 r = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
838 else /* link always up for AUI port or port auto select */
839 r = 1;
840 } else if (lp->chip_version > PCNET32_79C970A) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500841 ulong ioaddr = dev->base_addr; /* card base I/O address */
stephen hemminger1d70cb02011-09-16 11:06:26 +0000842 r = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
Don Fry8d916262006-08-22 10:22:37 -0700843 } else { /* can not detect link on really old chips */
844 r = 1;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500845 }
846 spin_unlock_irqrestore(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500848 return r;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849}
850
851static u32 pcnet32_get_msglevel(struct net_device *dev)
852{
Don Fry1e56a4b2007-03-06 10:55:00 -0800853 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500854 return lp->msg_enable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855}
856
857static void pcnet32_set_msglevel(struct net_device *dev, u32 value)
858{
Don Fry1e56a4b2007-03-06 10:55:00 -0800859 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500860 lp->msg_enable = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861}
862
863static int pcnet32_nway_reset(struct net_device *dev)
864{
Don Fry1e56a4b2007-03-06 10:55:00 -0800865 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500866 unsigned long flags;
867 int r = -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500869 if (lp->mii) {
870 spin_lock_irqsave(&lp->lock, flags);
871 r = mii_nway_restart(&lp->mii_if);
872 spin_unlock_irqrestore(&lp->lock, flags);
873 }
874 return r;
875}
876
877static void pcnet32_get_ringparam(struct net_device *dev,
878 struct ethtool_ringparam *ering)
879{
Don Fry1e56a4b2007-03-06 10:55:00 -0800880 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500881
Don Fry6dcd60c2006-06-29 13:53:23 -0700882 ering->tx_max_pending = TX_MAX_RING_SIZE;
883 ering->tx_pending = lp->tx_ring_size;
884 ering->rx_max_pending = RX_MAX_RING_SIZE;
885 ering->rx_pending = lp->rx_ring_size;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500886}
887
888static int pcnet32_set_ringparam(struct net_device *dev,
889 struct ethtool_ringparam *ering)
890{
Don Fry1e56a4b2007-03-06 10:55:00 -0800891 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500892 unsigned long flags;
Don Fry06c87852006-06-29 13:54:38 -0700893 unsigned int size;
894 ulong ioaddr = dev->base_addr;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500895 int i;
896
897 if (ering->rx_mini_pending || ering->rx_jumbo_pending)
898 return -EINVAL;
899
900 if (netif_running(dev))
Don Fry06c87852006-06-29 13:54:38 -0700901 pcnet32_netif_stop(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500902
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 spin_lock_irqsave(&lp->lock, flags);
stephen hemminger1d70cb02011-09-16 11:06:26 +0000904 lp->a->write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */
Don Fry06c87852006-06-29 13:54:38 -0700905
906 size = min(ering->tx_pending, (unsigned int)TX_MAX_RING_SIZE);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500907
908 /* set the minimum ring size to 4, to allow the loopback test to work
909 * unchanged.
910 */
911 for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
Don Fry06c87852006-06-29 13:54:38 -0700912 if (size <= (1 << i))
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500913 break;
914 }
Don Fry06c87852006-06-29 13:54:38 -0700915 if ((1 << i) != lp->tx_ring_size)
916 pcnet32_realloc_tx_ring(dev, lp, i);
Don Fryb368a3f2006-09-13 10:16:07 -0700917
Don Fry06c87852006-06-29 13:54:38 -0700918 size = min(ering->rx_pending, (unsigned int)RX_MAX_RING_SIZE);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500919 for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
Don Fry06c87852006-06-29 13:54:38 -0700920 if (size <= (1 << i))
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500921 break;
922 }
Don Fry06c87852006-06-29 13:54:38 -0700923 if ((1 << i) != lp->rx_ring_size)
924 pcnet32_realloc_rx_ring(dev, lp, i);
Don Fryb368a3f2006-09-13 10:16:07 -0700925
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700926 lp->napi.weight = lp->rx_ring_size / 2;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500927
Don Fry06c87852006-06-29 13:54:38 -0700928 if (netif_running(dev)) {
929 pcnet32_netif_start(dev);
930 pcnet32_restart(dev, CSR0_NORMAL);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500931 }
932
Don Frya88c8442005-11-01 12:04:33 -0800933 spin_unlock_irqrestore(&lp->lock, flags);
Hubert WS Lineabf0412005-09-14 11:39:25 -0700934
Joe Perches13ff83b2010-02-15 08:34:25 +0000935 netif_info(lp, drv, dev, "Ring Param Settings: RX: %d, TX: %d\n",
936 lp->rx_ring_size, lp->tx_ring_size);
Hubert WS Lineabf0412005-09-14 11:39:25 -0700937
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500938 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939}
940
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500941static void pcnet32_get_strings(struct net_device *dev, u32 stringset,
Joe Perches9e3f8062010-02-15 08:34:26 +0000942 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500944 memcpy(data, pcnet32_gstrings_test, sizeof(pcnet32_gstrings_test));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945}
946
Jeff Garzikb9f2c042007-10-03 18:07:32 -0700947static int pcnet32_get_sset_count(struct net_device *dev, int sset)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948{
Jeff Garzikb9f2c042007-10-03 18:07:32 -0700949 switch (sset) {
950 case ETH_SS_TEST:
951 return PCNET32_TEST_LEN;
952 default:
953 return -EOPNOTSUPP;
954 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955}
956
957static void pcnet32_ethtool_test(struct net_device *dev,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500958 struct ethtool_test *test, u64 * data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959{
Don Fry1e56a4b2007-03-06 10:55:00 -0800960 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500961 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500963 if (test->flags == ETH_TEST_FL_OFFLINE) {
964 rc = pcnet32_loopback_test(dev, data);
965 if (rc) {
Joe Perches13ff83b2010-02-15 08:34:25 +0000966 netif_printk(lp, hw, KERN_DEBUG, dev,
967 "Loopback test failed\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500968 test->flags |= ETH_TEST_FL_FAILED;
Joe Perches13ff83b2010-02-15 08:34:25 +0000969 } else
970 netif_printk(lp, hw, KERN_DEBUG, dev,
971 "Loopback test passed\n");
972 } else
973 netif_printk(lp, hw, KERN_DEBUG, dev,
974 "No tests to run (specify 'Offline' on ethtool)\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500975} /* end pcnet32_ethtool_test */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500977static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978{
Don Fry1e56a4b2007-03-06 10:55:00 -0800979 struct pcnet32_private *lp = netdev_priv(dev);
stephen hemminger1d70cb02011-09-16 11:06:26 +0000980 const struct pcnet32_access *a = lp->a; /* access to registers */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500981 ulong ioaddr = dev->base_addr; /* card base I/O address */
982 struct sk_buff *skb; /* sk buff */
983 int x, i; /* counters */
984 int numbuffs = 4; /* number of TX/RX buffers and descs */
985 u16 status = 0x8300; /* TX ring status */
Al Viro3e335452007-08-23 00:45:46 -0400986 __le16 teststatus; /* test of ring status */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500987 int rc; /* return code */
988 int size; /* size of packets */
989 unsigned char *packet; /* source packet data */
990 static const int data_len = 60; /* length of source packets */
991 unsigned long flags;
992 unsigned long ticks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500994 rc = 1; /* default to fail */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500996 if (netif_running(dev))
Don Fry7de745e2006-09-13 10:16:53 -0700997 pcnet32_netif_stop(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
Jeff Garzik4a5e8e22006-03-21 16:15:44 -0500999 spin_lock_irqsave(&lp->lock, flags);
stephen hemminger1d70cb02011-09-16 11:06:26 +00001000 lp->a->write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */
Don Fryac5bfe42006-06-29 13:55:27 -07001001
1002 numbuffs = min(numbuffs, (int)min(lp->rx_ring_size, lp->tx_ring_size));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001004 /* Reset the PCNET32 */
stephen hemminger1d70cb02011-09-16 11:06:26 +00001005 lp->a->reset(ioaddr);
1006 lp->a->write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001008 /* switch pcnet32 to 32bit mode */
stephen hemminger1d70cb02011-09-16 11:06:26 +00001009 lp->a->write_bcr(ioaddr, 20, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001011 /* purge & init rings but don't actually restart */
1012 pcnet32_restart(dev, 0x0000);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013
stephen hemminger1d70cb02011-09-16 11:06:26 +00001014 lp->a->write_csr(ioaddr, CSR0, CSR0_STOP); /* Set STOP bit */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001016 /* Initialize Transmit buffers. */
1017 size = data_len + 15;
1018 for (x = 0; x < numbuffs; x++) {
Pradeep A Dalvi1d266432012-02-05 02:49:09 +00001019 skb = netdev_alloc_skb(dev, size);
Joe Perches9e3f8062010-02-15 08:34:26 +00001020 if (!skb) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001021 netif_printk(lp, hw, KERN_DEBUG, dev,
1022 "Cannot allocate skb at line: %d!\n",
1023 __LINE__);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001024 goto clean_up;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001025 }
Joe Perches9e3f8062010-02-15 08:34:26 +00001026 packet = skb->data;
1027 skb_put(skb, size); /* create space for data */
1028 lp->tx_skbuff[x] = skb;
1029 lp->tx_ring[x].length = cpu_to_le16(-skb->len);
1030 lp->tx_ring[x].misc = 0;
1031
1032 /* put DA and SA into the skb */
1033 for (i = 0; i < 6; i++)
1034 *packet++ = dev->dev_addr[i];
1035 for (i = 0; i < 6; i++)
1036 *packet++ = dev->dev_addr[i];
1037 /* type */
1038 *packet++ = 0x08;
1039 *packet++ = 0x06;
1040 /* packet number */
1041 *packet++ = x;
1042 /* fill packet with data */
1043 for (i = 0; i < data_len; i++)
1044 *packet++ = i;
1045
1046 lp->tx_dma_addr[x] =
1047 pci_map_single(lp->pci_dev, skb->data, skb->len,
1048 PCI_DMA_TODEVICE);
Don Fry4cc5c472014-02-17 20:57:59 -08001049 if (pci_dma_mapping_error(lp->pci_dev, lp->tx_dma_addr[x])) {
1050 netif_printk(lp, hw, KERN_DEBUG, dev,
1051 "DMA mapping error at line: %d!\n",
1052 __LINE__);
1053 goto clean_up;
1054 }
Joe Perches9e3f8062010-02-15 08:34:26 +00001055 lp->tx_ring[x].base = cpu_to_le32(lp->tx_dma_addr[x]);
1056 wmb(); /* Make sure owner changes after all others are visible */
1057 lp->tx_ring[x].status = cpu_to_le16(status);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001058 }
1059
Don Fryac5bfe42006-06-29 13:55:27 -07001060 x = a->read_bcr(ioaddr, 32); /* set internal loopback in BCR32 */
1061 a->write_bcr(ioaddr, 32, x | 0x0002);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001062
Don Fryac5bfe42006-06-29 13:55:27 -07001063 /* set int loopback in CSR15 */
1064 x = a->read_csr(ioaddr, CSR15) & 0xfffc;
stephen hemminger1d70cb02011-09-16 11:06:26 +00001065 lp->a->write_csr(ioaddr, CSR15, x | 0x0044);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001066
Al Viro3e335452007-08-23 00:45:46 -04001067 teststatus = cpu_to_le16(0x8000);
stephen hemminger1d70cb02011-09-16 11:06:26 +00001068 lp->a->write_csr(ioaddr, CSR0, CSR0_START); /* Set STRT bit */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001069
1070 /* Check status of descriptors */
1071 for (x = 0; x < numbuffs; x++) {
1072 ticks = 0;
1073 rmb();
1074 while ((lp->rx_ring[x].status & teststatus) && (ticks < 200)) {
1075 spin_unlock_irqrestore(&lp->lock, flags);
Don Fryac5bfe42006-06-29 13:55:27 -07001076 msleep(1);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001077 spin_lock_irqsave(&lp->lock, flags);
1078 rmb();
1079 ticks++;
1080 }
1081 if (ticks == 200) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001082 netif_err(lp, hw, dev, "Desc %d failed to reset!\n", x);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001083 break;
1084 }
1085 }
1086
stephen hemminger1d70cb02011-09-16 11:06:26 +00001087 lp->a->write_csr(ioaddr, CSR0, CSR0_STOP); /* Set STOP bit */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001088 wmb();
1089 if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001090 netdev_printk(KERN_DEBUG, dev, "RX loopback packets:\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001091
1092 for (x = 0; x < numbuffs; x++) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001093 netdev_printk(KERN_DEBUG, dev, "Packet %d: ", x);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001094 skb = lp->rx_skbuff[x];
Joe Perches9e3f8062010-02-15 08:34:26 +00001095 for (i = 0; i < size; i++)
Joe Perches13ff83b2010-02-15 08:34:25 +00001096 pr_cont(" %02x", *(skb->data + i));
Joe Perches13ff83b2010-02-15 08:34:25 +00001097 pr_cont("\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001098 }
1099 }
1100
1101 x = 0;
1102 rc = 0;
1103 while (x < numbuffs && !rc) {
1104 skb = lp->rx_skbuff[x];
1105 packet = lp->tx_skbuff[x]->data;
1106 for (i = 0; i < size; i++) {
1107 if (*(skb->data + i) != packet[i]) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001108 netif_printk(lp, hw, KERN_DEBUG, dev,
1109 "Error in compare! %2x - %02x %02x\n",
1110 i, *(skb->data + i), packet[i]);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001111 rc = 1;
1112 break;
1113 }
1114 }
1115 x++;
1116 }
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001117
Joe Perches9e3f8062010-02-15 08:34:26 +00001118clean_up:
Don Fryac5bfe42006-06-29 13:55:27 -07001119 *data1 = rc;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001120 pcnet32_purge_tx_ring(dev);
Don Fryac5bfe42006-06-29 13:55:27 -07001121
1122 x = a->read_csr(ioaddr, CSR15);
1123 a->write_csr(ioaddr, CSR15, (x & ~0x0044)); /* reset bits 6 and 2 */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001124
1125 x = a->read_bcr(ioaddr, 32); /* reset internal loopback */
Don Fryac5bfe42006-06-29 13:55:27 -07001126 a->write_bcr(ioaddr, 32, (x & ~0x0002));
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001127
Don Fry7de745e2006-09-13 10:16:53 -07001128 if (netif_running(dev)) {
1129 pcnet32_netif_start(dev);
1130 pcnet32_restart(dev, CSR0_NORMAL);
1131 } else {
1132 pcnet32_purge_rx_ring(dev);
stephen hemminger1d70cb02011-09-16 11:06:26 +00001133 lp->a->write_bcr(ioaddr, 20, 4); /* return to 16bit mode */
Don Fry7de745e2006-09-13 10:16:53 -07001134 }
1135 spin_unlock_irqrestore(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136
Joe Perches9e3f8062010-02-15 08:34:26 +00001137 return rc;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001138} /* end pcnet32_loopback_test */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139
stephen hemminger9871acf2011-04-04 11:06:41 +00001140static int pcnet32_set_phys_id(struct net_device *dev,
1141 enum ethtool_phys_id_state state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142{
Don Fry1e56a4b2007-03-06 10:55:00 -08001143 struct pcnet32_private *lp = netdev_priv(dev);
stephen hemminger1d70cb02011-09-16 11:06:26 +00001144 const struct pcnet32_access *a = lp->a;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001145 ulong ioaddr = dev->base_addr;
1146 unsigned long flags;
1147 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148
stephen hemminger9871acf2011-04-04 11:06:41 +00001149 switch (state) {
1150 case ETHTOOL_ID_ACTIVE:
1151 /* Save the current value of the bcrs */
1152 spin_lock_irqsave(&lp->lock, flags);
1153 for (i = 4; i < 8; i++)
1154 lp->save_regs[i - 4] = a->read_bcr(ioaddr, i);
1155 spin_unlock_irqrestore(&lp->lock, flags);
Allan, Bruce Wfce55922011-04-13 13:09:10 +00001156 return 2; /* cycle on/off twice per second */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157
stephen hemminger9871acf2011-04-04 11:06:41 +00001158 case ETHTOOL_ID_ON:
1159 case ETHTOOL_ID_OFF:
1160 /* Blink the led */
1161 spin_lock_irqsave(&lp->lock, flags);
1162 for (i = 4; i < 8; i++)
1163 a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
1164 spin_unlock_irqrestore(&lp->lock, flags);
1165 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
stephen hemminger9871acf2011-04-04 11:06:41 +00001167 case ETHTOOL_ID_INACTIVE:
1168 /* Restore the original value of the bcrs */
1169 spin_lock_irqsave(&lp->lock, flags);
1170 for (i = 4; i < 8; i++)
1171 a->write_bcr(ioaddr, i, lp->save_regs[i - 4]);
1172 spin_unlock_irqrestore(&lp->lock, flags);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001173 }
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001174 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175}
1176
Don Frydf27f4a2006-06-29 13:55:02 -07001177/*
Don Fry3904c322006-09-13 10:16:38 -07001178 * process one receive descriptor entry
1179 */
Don Fry9691edd2006-09-13 10:16:21 -07001180
Don Fry3904c322006-09-13 10:16:38 -07001181static void pcnet32_rx_entry(struct net_device *dev,
1182 struct pcnet32_private *lp,
1183 struct pcnet32_rx_head *rxp,
1184 int entry)
1185{
1186 int status = (short)le16_to_cpu(rxp->status) >> 8;
1187 int rx_in_place = 0;
1188 struct sk_buff *skb;
1189 short pkt_len;
1190
1191 if (status != 0x03) { /* There was an error. */
1192 /*
1193 * There is a tricky error noted by John Murphy,
1194 * <murf@perftech.com> to Russ Nelson: Even with full-sized
1195 * buffers it's possible for a jabber packet to use two
1196 * buffers, with only the last correctly noting the error.
1197 */
1198 if (status & 0x01) /* Only count a general error at the */
Don Fry4f1e5ba2007-10-17 17:06:19 -07001199 dev->stats.rx_errors++; /* end of a packet. */
Don Fry3904c322006-09-13 10:16:38 -07001200 if (status & 0x20)
Don Fry4f1e5ba2007-10-17 17:06:19 -07001201 dev->stats.rx_frame_errors++;
Don Fry3904c322006-09-13 10:16:38 -07001202 if (status & 0x10)
Don Fry4f1e5ba2007-10-17 17:06:19 -07001203 dev->stats.rx_over_errors++;
Don Fry3904c322006-09-13 10:16:38 -07001204 if (status & 0x08)
Don Fry4f1e5ba2007-10-17 17:06:19 -07001205 dev->stats.rx_crc_errors++;
Don Fry3904c322006-09-13 10:16:38 -07001206 if (status & 0x04)
Don Fry4f1e5ba2007-10-17 17:06:19 -07001207 dev->stats.rx_fifo_errors++;
Don Fry3904c322006-09-13 10:16:38 -07001208 return;
1209 }
1210
1211 pkt_len = (le32_to_cpu(rxp->msg_length) & 0xfff) - 4;
1212
1213 /* Discard oversize frames. */
Don Fry232c5642008-02-08 07:32:26 -08001214 if (unlikely(pkt_len > PKT_BUF_SIZE)) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001215 netif_err(lp, drv, dev, "Impossible packet size %d!\n",
1216 pkt_len);
Don Fry4f1e5ba2007-10-17 17:06:19 -07001217 dev->stats.rx_errors++;
Don Fry3904c322006-09-13 10:16:38 -07001218 return;
1219 }
1220 if (pkt_len < 60) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001221 netif_err(lp, rx_err, dev, "Runt packet!\n");
Don Fry4f1e5ba2007-10-17 17:06:19 -07001222 dev->stats.rx_errors++;
Don Fry3904c322006-09-13 10:16:38 -07001223 return;
1224 }
1225
1226 if (pkt_len > rx_copybreak) {
1227 struct sk_buff *newskb;
Don Fry4cc5c472014-02-17 20:57:59 -08001228 dma_addr_t new_dma_addr;
Don Fry3904c322006-09-13 10:16:38 -07001229
Pradeep A Dalvi1d266432012-02-05 02:49:09 +00001230 newskb = netdev_alloc_skb(dev, PKT_BUF_SKB);
Don Fry4cc5c472014-02-17 20:57:59 -08001231 /*
1232 * map the new buffer, if mapping fails, drop the packet and
1233 * reuse the old buffer
1234 */
Joe Perches9e3f8062010-02-15 08:34:26 +00001235 if (newskb) {
Don Fry232c5642008-02-08 07:32:26 -08001236 skb_reserve(newskb, NET_IP_ALIGN);
Don Fry4cc5c472014-02-17 20:57:59 -08001237 new_dma_addr = pci_map_single(lp->pci_dev,
1238 newskb->data,
1239 PKT_BUF_SIZE,
1240 PCI_DMA_FROMDEVICE);
1241 if (pci_dma_mapping_error(lp->pci_dev, new_dma_addr)) {
1242 netif_err(lp, rx_err, dev,
1243 "DMA mapping error.\n");
1244 dev_kfree_skb(newskb);
1245 skb = NULL;
1246 } else {
1247 skb = lp->rx_skbuff[entry];
1248 pci_unmap_single(lp->pci_dev,
1249 lp->rx_dma_addr[entry],
1250 PKT_BUF_SIZE,
1251 PCI_DMA_FROMDEVICE);
1252 skb_put(skb, pkt_len);
1253 lp->rx_skbuff[entry] = newskb;
1254 lp->rx_dma_addr[entry] = new_dma_addr;
1255 rxp->base = cpu_to_le32(new_dma_addr);
1256 rx_in_place = 1;
1257 }
Don Fry3904c322006-09-13 10:16:38 -07001258 } else
1259 skb = NULL;
Joe Perches9e3f8062010-02-15 08:34:26 +00001260 } else
Pradeep A Dalvi1d266432012-02-05 02:49:09 +00001261 skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN);
Don Fry3904c322006-09-13 10:16:38 -07001262
1263 if (skb == NULL) {
Don Fry4f1e5ba2007-10-17 17:06:19 -07001264 dev->stats.rx_dropped++;
Don Fry3904c322006-09-13 10:16:38 -07001265 return;
1266 }
Don Fry3904c322006-09-13 10:16:38 -07001267 if (!rx_in_place) {
Don Fry232c5642008-02-08 07:32:26 -08001268 skb_reserve(skb, NET_IP_ALIGN);
Don Fry3904c322006-09-13 10:16:38 -07001269 skb_put(skb, pkt_len); /* Make room */
1270 pci_dma_sync_single_for_cpu(lp->pci_dev,
1271 lp->rx_dma_addr[entry],
Don Fryb2cbbd82007-03-05 18:13:09 -08001272 pkt_len,
Don Fry3904c322006-09-13 10:16:38 -07001273 PCI_DMA_FROMDEVICE);
David S. Miller8c7b7fa2007-07-10 22:08:12 -07001274 skb_copy_to_linear_data(skb,
Don Fry3904c322006-09-13 10:16:38 -07001275 (unsigned char *)(lp->rx_skbuff[entry]->data),
David S. Miller8c7b7fa2007-07-10 22:08:12 -07001276 pkt_len);
Don Fry3904c322006-09-13 10:16:38 -07001277 pci_dma_sync_single_for_device(lp->pci_dev,
1278 lp->rx_dma_addr[entry],
Don Fryb2cbbd82007-03-05 18:13:09 -08001279 pkt_len,
Don Fry3904c322006-09-13 10:16:38 -07001280 PCI_DMA_FROMDEVICE);
1281 }
Don Fry4f1e5ba2007-10-17 17:06:19 -07001282 dev->stats.rx_bytes += skb->len;
Don Fry3904c322006-09-13 10:16:38 -07001283 skb->protocol = eth_type_trans(skb, dev);
Don Fry7de745e2006-09-13 10:16:53 -07001284 netif_receive_skb(skb);
Don Fry4f1e5ba2007-10-17 17:06:19 -07001285 dev->stats.rx_packets++;
Don Fry3904c322006-09-13 10:16:38 -07001286}
1287
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001288static int pcnet32_rx(struct net_device *dev, int budget)
Don Fry9691edd2006-09-13 10:16:21 -07001289{
Don Fry1e56a4b2007-03-06 10:55:00 -08001290 struct pcnet32_private *lp = netdev_priv(dev);
Don Fry9691edd2006-09-13 10:16:21 -07001291 int entry = lp->cur_rx & lp->rx_mod_mask;
Don Fry3904c322006-09-13 10:16:38 -07001292 struct pcnet32_rx_head *rxp = &lp->rx_ring[entry];
1293 int npackets = 0;
Don Fry9691edd2006-09-13 10:16:21 -07001294
1295 /* If we own the next entry, it's a new packet. Send it up. */
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001296 while (npackets < budget && (short)le16_to_cpu(rxp->status) >= 0) {
Don Fry3904c322006-09-13 10:16:38 -07001297 pcnet32_rx_entry(dev, lp, rxp, entry);
1298 npackets += 1;
Don Fry9691edd2006-09-13 10:16:21 -07001299 /*
Don Fry3904c322006-09-13 10:16:38 -07001300 * The docs say that the buffer length isn't touched, but Andrew
1301 * Boyd of QNX reports that some revs of the 79C965 clear it.
Don Fry9691edd2006-09-13 10:16:21 -07001302 */
Don Fry232c5642008-02-08 07:32:26 -08001303 rxp->buf_length = cpu_to_le16(NEG_BUF_SIZE);
Don Fry3904c322006-09-13 10:16:38 -07001304 wmb(); /* Make sure owner changes after others are visible */
Al Viro3e335452007-08-23 00:45:46 -04001305 rxp->status = cpu_to_le16(0x8000);
Don Fry9691edd2006-09-13 10:16:21 -07001306 entry = (++lp->cur_rx) & lp->rx_mod_mask;
Don Fry3904c322006-09-13 10:16:38 -07001307 rxp = &lp->rx_ring[entry];
Don Fry9691edd2006-09-13 10:16:21 -07001308 }
1309
Don Fry7de745e2006-09-13 10:16:53 -07001310 return npackets;
Don Fry9691edd2006-09-13 10:16:21 -07001311}
1312
Don Fry7de745e2006-09-13 10:16:53 -07001313static int pcnet32_tx(struct net_device *dev)
Don Fry9691edd2006-09-13 10:16:21 -07001314{
Don Fry1e56a4b2007-03-06 10:55:00 -08001315 struct pcnet32_private *lp = netdev_priv(dev);
Don Fry9691edd2006-09-13 10:16:21 -07001316 unsigned int dirty_tx = lp->dirty_tx;
1317 int delta;
1318 int must_restart = 0;
1319
1320 while (dirty_tx != lp->cur_tx) {
1321 int entry = dirty_tx & lp->tx_mod_mask;
1322 int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
1323
1324 if (status < 0)
1325 break; /* It still hasn't been Txed */
1326
1327 lp->tx_ring[entry].base = 0;
1328
1329 if (status & 0x4000) {
Don Fry3904c322006-09-13 10:16:38 -07001330 /* There was a major error, log it. */
Don Fry9691edd2006-09-13 10:16:21 -07001331 int err_status = le32_to_cpu(lp->tx_ring[entry].misc);
Don Fry4f1e5ba2007-10-17 17:06:19 -07001332 dev->stats.tx_errors++;
Joe Perches13ff83b2010-02-15 08:34:25 +00001333 netif_err(lp, tx_err, dev,
1334 "Tx error status=%04x err_status=%08x\n",
1335 status, err_status);
Don Fry9691edd2006-09-13 10:16:21 -07001336 if (err_status & 0x04000000)
Don Fry4f1e5ba2007-10-17 17:06:19 -07001337 dev->stats.tx_aborted_errors++;
Don Fry9691edd2006-09-13 10:16:21 -07001338 if (err_status & 0x08000000)
Don Fry4f1e5ba2007-10-17 17:06:19 -07001339 dev->stats.tx_carrier_errors++;
Don Fry9691edd2006-09-13 10:16:21 -07001340 if (err_status & 0x10000000)
Don Fry4f1e5ba2007-10-17 17:06:19 -07001341 dev->stats.tx_window_errors++;
Don Fry9691edd2006-09-13 10:16:21 -07001342#ifndef DO_DXSUFLO
1343 if (err_status & 0x40000000) {
Don Fry4f1e5ba2007-10-17 17:06:19 -07001344 dev->stats.tx_fifo_errors++;
Don Fry9691edd2006-09-13 10:16:21 -07001345 /* Ackk! On FIFO errors the Tx unit is turned off! */
1346 /* Remove this verbosity later! */
Joe Perches13ff83b2010-02-15 08:34:25 +00001347 netif_err(lp, tx_err, dev, "Tx FIFO error!\n");
Don Fry9691edd2006-09-13 10:16:21 -07001348 must_restart = 1;
1349 }
1350#else
1351 if (err_status & 0x40000000) {
Don Fry4f1e5ba2007-10-17 17:06:19 -07001352 dev->stats.tx_fifo_errors++;
Don Fry9691edd2006-09-13 10:16:21 -07001353 if (!lp->dxsuflo) { /* If controller doesn't recover ... */
1354 /* Ackk! On FIFO errors the Tx unit is turned off! */
1355 /* Remove this verbosity later! */
Joe Perches13ff83b2010-02-15 08:34:25 +00001356 netif_err(lp, tx_err, dev, "Tx FIFO error!\n");
Don Fry9691edd2006-09-13 10:16:21 -07001357 must_restart = 1;
1358 }
1359 }
1360#endif
1361 } else {
1362 if (status & 0x1800)
Don Fry4f1e5ba2007-10-17 17:06:19 -07001363 dev->stats.collisions++;
1364 dev->stats.tx_packets++;
Don Fry9691edd2006-09-13 10:16:21 -07001365 }
1366
1367 /* We must free the original skb */
1368 if (lp->tx_skbuff[entry]) {
1369 pci_unmap_single(lp->pci_dev,
1370 lp->tx_dma_addr[entry],
1371 lp->tx_skbuff[entry]->
1372 len, PCI_DMA_TODEVICE);
Don Fry3904c322006-09-13 10:16:38 -07001373 dev_kfree_skb_any(lp->tx_skbuff[entry]);
Don Fry9691edd2006-09-13 10:16:21 -07001374 lp->tx_skbuff[entry] = NULL;
1375 lp->tx_dma_addr[entry] = 0;
1376 }
1377 dirty_tx++;
1378 }
1379
Don Fry3904c322006-09-13 10:16:38 -07001380 delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
Don Fry9691edd2006-09-13 10:16:21 -07001381 if (delta > lp->tx_ring_size) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001382 netif_err(lp, drv, dev, "out-of-sync dirty pointer, %d vs. %d, full=%d\n",
1383 dirty_tx, lp->cur_tx, lp->tx_full);
Don Fry9691edd2006-09-13 10:16:21 -07001384 dirty_tx += lp->tx_ring_size;
1385 delta -= lp->tx_ring_size;
1386 }
1387
1388 if (lp->tx_full &&
1389 netif_queue_stopped(dev) &&
1390 delta < lp->tx_ring_size - 2) {
1391 /* The ring is no longer full, clear tbusy. */
1392 lp->tx_full = 0;
1393 netif_wake_queue(dev);
1394 }
1395 lp->dirty_tx = dirty_tx;
1396
1397 return must_restart;
1398}
1399
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001400static int pcnet32_poll(struct napi_struct *napi, int budget)
Don Fry7de745e2006-09-13 10:16:53 -07001401{
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001402 struct pcnet32_private *lp = container_of(napi, struct pcnet32_private, napi);
1403 struct net_device *dev = lp->dev;
Don Fry7de745e2006-09-13 10:16:53 -07001404 unsigned long ioaddr = dev->base_addr;
1405 unsigned long flags;
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001406 int work_done;
Don Fry7de745e2006-09-13 10:16:53 -07001407 u16 val;
1408
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001409 work_done = pcnet32_rx(dev, budget);
Don Fry7de745e2006-09-13 10:16:53 -07001410
1411 spin_lock_irqsave(&lp->lock, flags);
1412 if (pcnet32_tx(dev)) {
1413 /* reset the chip to clear the error condition, then restart */
stephen hemminger1d70cb02011-09-16 11:06:26 +00001414 lp->a->reset(ioaddr);
1415 lp->a->write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
Don Fry7de745e2006-09-13 10:16:53 -07001416 pcnet32_restart(dev, CSR0_START);
1417 netif_wake_queue(dev);
1418 }
Don Fry7de745e2006-09-13 10:16:53 -07001419
Eric Dumazet5b2ec6f2017-02-04 15:24:55 -08001420 if (work_done < budget && napi_complete_done(napi, work_done)) {
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001421 /* clear interrupt masks */
stephen hemminger1d70cb02011-09-16 11:06:26 +00001422 val = lp->a->read_csr(ioaddr, CSR3);
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001423 val &= 0x00ff;
stephen hemminger1d70cb02011-09-16 11:06:26 +00001424 lp->a->write_csr(ioaddr, CSR3, val);
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001425
1426 /* Set interrupt enable. */
stephen hemminger1d70cb02011-09-16 11:06:26 +00001427 lp->a->write_csr(ioaddr, CSR0, CSR0_INTEN);
Don Fry7de745e2006-09-13 10:16:53 -07001428 }
Eric Dumazet5b2ec6f2017-02-04 15:24:55 -08001429
1430 spin_unlock_irqrestore(&lp->lock, flags);
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001431 return work_done;
Don Fry7de745e2006-09-13 10:16:53 -07001432}
Don Fry7de745e2006-09-13 10:16:53 -07001433
Don Fryac62ef02006-03-20 15:26:03 -08001434#define PCNET32_REGS_PER_PHY 32
1435#define PCNET32_MAX_PHYS 32
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436static int pcnet32_get_regs_len(struct net_device *dev)
1437{
Don Fry1e56a4b2007-03-06 10:55:00 -08001438 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001439 int j = lp->phycount * PCNET32_REGS_PER_PHY;
Don Fryac62ef02006-03-20 15:26:03 -08001440
Joe Perches9e3f8062010-02-15 08:34:26 +00001441 return (PCNET32_NUM_REGS + j) * sizeof(u16);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442}
1443
1444static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001445 void *ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001447 int i, csr0;
1448 u16 *buff = ptr;
Don Fry1e56a4b2007-03-06 10:55:00 -08001449 struct pcnet32_private *lp = netdev_priv(dev);
stephen hemminger1d70cb02011-09-16 11:06:26 +00001450 const struct pcnet32_access *a = lp->a;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001451 ulong ioaddr = dev->base_addr;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001452 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001454 spin_lock_irqsave(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
Don Frydf27f4a2006-06-29 13:55:02 -07001456 csr0 = a->read_csr(ioaddr, CSR0);
1457 if (!(csr0 & CSR0_STOP)) /* If not stopped */
1458 pcnet32_suspend(dev, &flags, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001460 /* read address PROM */
1461 for (i = 0; i < 16; i += 2)
1462 *buff++ = inw(ioaddr + i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001464 /* read control and status registers */
Joe Perches9e3f8062010-02-15 08:34:26 +00001465 for (i = 0; i < 90; i++)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001466 *buff++ = a->read_csr(ioaddr, i);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001467
1468 *buff++ = a->read_csr(ioaddr, 112);
1469 *buff++ = a->read_csr(ioaddr, 114);
1470
1471 /* read bus configuration registers */
Joe Perches9e3f8062010-02-15 08:34:26 +00001472 for (i = 0; i < 30; i++)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001473 *buff++ = a->read_bcr(ioaddr, i);
Joe Perches9e3f8062010-02-15 08:34:26 +00001474
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001475 *buff++ = 0; /* skip bcr30 so as not to hang 79C976 */
Joe Perches9e3f8062010-02-15 08:34:26 +00001476
1477 for (i = 31; i < 36; i++)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001478 *buff++ = a->read_bcr(ioaddr, i);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001479
1480 /* read mii phy registers */
1481 if (lp->mii) {
1482 int j;
1483 for (j = 0; j < PCNET32_MAX_PHYS; j++) {
1484 if (lp->phymask & (1 << j)) {
1485 for (i = 0; i < PCNET32_REGS_PER_PHY; i++) {
stephen hemminger1d70cb02011-09-16 11:06:26 +00001486 lp->a->write_bcr(ioaddr, 33,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001487 (j << 5) | i);
stephen hemminger1d70cb02011-09-16 11:06:26 +00001488 *buff++ = lp->a->read_bcr(ioaddr, 34);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001489 }
1490 }
1491 }
1492 }
1493
Ondrej Zarycce5fba2017-02-13 23:45:46 +01001494 if (!(csr0 & CSR0_STOP)) /* If not stopped */
1495 pcnet32_clr_suspend(lp, ioaddr);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001496
1497 spin_unlock_irqrestore(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498}
1499
Jeff Garzik7282d492006-09-13 14:30:00 -04001500static const struct ethtool_ops pcnet32_ethtool_ops = {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001501 .get_drvinfo = pcnet32_get_drvinfo,
1502 .get_msglevel = pcnet32_get_msglevel,
1503 .set_msglevel = pcnet32_set_msglevel,
1504 .nway_reset = pcnet32_nway_reset,
1505 .get_link = pcnet32_get_link,
1506 .get_ringparam = pcnet32_get_ringparam,
1507 .set_ringparam = pcnet32_set_ringparam,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001508 .get_strings = pcnet32_get_strings,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001509 .self_test = pcnet32_ethtool_test,
stephen hemminger9871acf2011-04-04 11:06:41 +00001510 .set_phys_id = pcnet32_set_phys_id,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001511 .get_regs_len = pcnet32_get_regs_len,
1512 .get_regs = pcnet32_get_regs,
Jeff Garzikb9f2c042007-10-03 18:07:32 -07001513 .get_sset_count = pcnet32_get_sset_count,
Philippe Reynesea74df82016-11-06 00:26:41 +01001514 .get_link_ksettings = pcnet32_get_link_ksettings,
1515 .set_link_ksettings = pcnet32_set_link_ksettings,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516};
1517
1518/* only probes for non-PCI devices, the rest are handled by
1519 * pci_register_driver via pcnet32_probe_pci */
1520
Bill Pembertona9590872012-12-03 09:22:56 -05001521static void pcnet32_probe_vlbus(unsigned int *pcnet32_portlist)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001523 unsigned int *port, ioaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001525 /* search for PCnet32 VLB cards at known addresses */
1526 for (port = pcnet32_portlist; (ioaddr = *port); port++) {
1527 if (request_region
1528 (ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_vlbus")) {
1529 /* check if there is really a pcnet chip on that ioaddr */
Joe Perches8e95a202009-12-03 07:58:21 +00001530 if ((inb(ioaddr + 14) == 0x57) &&
1531 (inb(ioaddr + 15) == 0x57)) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001532 pcnet32_probe1(ioaddr, 0, NULL);
1533 } else {
1534 release_region(ioaddr, PCNET32_TOTAL_SIZE);
1535 }
1536 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538}
1539
Bill Pembertona9590872012-12-03 09:22:56 -05001540static int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
1542{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001543 unsigned long ioaddr;
1544 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001546 err = pci_enable_device(pdev);
1547 if (err < 0) {
1548 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001549 pr_err("failed to enable device -- err=%d\n", err);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001550 return err;
1551 }
1552 pci_set_master(pdev);
1553
1554 ioaddr = pci_resource_start(pdev, 0);
1555 if (!ioaddr) {
1556 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001557 pr_err("card has no PCI IO resources, aborting\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001558 return -ENODEV;
1559 }
1560
Christoph Hellwig1a47de62015-11-20 15:57:07 -08001561 err = pci_set_dma_mask(pdev, PCNET32_DMA_MASK);
1562 if (err) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001563 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001564 pr_err("architecture does not support 32bit PCI busmaster DMA\n");
Christoph Hellwig1a47de62015-11-20 15:57:07 -08001565 return err;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001566 }
Joe Perches9e3f8062010-02-15 08:34:26 +00001567 if (!request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci")) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001568 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001569 pr_err("io address range already allocated\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001570 return -EBUSY;
1571 }
1572
1573 err = pcnet32_probe1(ioaddr, 1, pdev);
Joe Perches9e3f8062010-02-15 08:34:26 +00001574 if (err < 0)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001575 pci_disable_device(pdev);
Joe Perches9e3f8062010-02-15 08:34:26 +00001576
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578}
1579
Stephen Hemminger3bc124d2009-01-07 17:29:16 -08001580static const struct net_device_ops pcnet32_netdev_ops = {
1581 .ndo_open = pcnet32_open,
1582 .ndo_stop = pcnet32_close,
1583 .ndo_start_xmit = pcnet32_start_xmit,
1584 .ndo_tx_timeout = pcnet32_tx_timeout,
1585 .ndo_get_stats = pcnet32_get_stats,
Jiri Pirkoafc4b132011-08-16 06:29:01 +00001586 .ndo_set_rx_mode = pcnet32_set_multicast_list,
Stephen Hemminger3bc124d2009-01-07 17:29:16 -08001587 .ndo_do_ioctl = pcnet32_ioctl,
Stephen Hemminger3bc124d2009-01-07 17:29:16 -08001588 .ndo_set_mac_address = eth_mac_addr,
1589 .ndo_validate_addr = eth_validate_addr,
1590#ifdef CONFIG_NET_POLL_CONTROLLER
1591 .ndo_poll_controller = pcnet32_poll_controller,
1592#endif
1593};
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595/* pcnet32_probe1
1596 * Called from both pcnet32_probe_vlbus and pcnet_probe_pci.
1597 * pdev will be NULL when called from pcnet32_probe_vlbus.
1598 */
Bill Pembertona9590872012-12-03 09:22:56 -05001599static int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1601{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001602 struct pcnet32_private *lp;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001603 int i, media;
Markos Chandras87f966d2015-03-19 10:28:14 +00001604 int fdx, mii, fset, dxsuflo, sram;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001605 int chip_version;
1606 char *chipname;
1607 struct net_device *dev;
stephen hemminger1d70cb02011-09-16 11:06:26 +00001608 const struct pcnet32_access *a = NULL;
Joe Perches1409a932013-08-01 16:17:49 -07001609 u8 promaddr[ETH_ALEN];
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001610 int ret = -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001612 /* reset the chip */
1613 pcnet32_wio_reset(ioaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001615 /* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */
1616 if (pcnet32_wio_read_csr(ioaddr, 0) == 4 && pcnet32_wio_check(ioaddr)) {
1617 a = &pcnet32_wio;
1618 } else {
1619 pcnet32_dwio_reset(ioaddr);
Joe Perches8e95a202009-12-03 07:58:21 +00001620 if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 &&
1621 pcnet32_dwio_check(ioaddr)) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001622 a = &pcnet32_dwio;
Don Frydf4e7f72009-07-31 08:40:06 +00001623 } else {
1624 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001625 pr_err("No access methods\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001626 goto err_release_region;
Don Frydf4e7f72009-07-31 08:40:06 +00001627 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001630 chip_version =
1631 a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr, 89) << 16);
1632 if ((pcnet32_debug & NETIF_MSG_PROBE) && (pcnet32_debug & NETIF_MSG_HW))
Joe Perches13ff83b2010-02-15 08:34:25 +00001633 pr_info(" PCnet chip version is %#x\n", chip_version);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001634 if ((chip_version & 0xfff) != 0x003) {
1635 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001636 pr_info("Unsupported chip version\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001637 goto err_release_region;
1638 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001640 /* initialize variables */
Markos Chandras87f966d2015-03-19 10:28:14 +00001641 fdx = mii = fset = dxsuflo = sram = 0;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001642 chip_version = (chip_version >> 12) & 0xffff;
1643
1644 switch (chip_version) {
1645 case 0x2420:
1646 chipname = "PCnet/PCI 79C970"; /* PCI */
1647 break;
1648 case 0x2430:
1649 if (shared)
1650 chipname = "PCnet/PCI 79C970"; /* 970 gives the wrong chip id back */
1651 else
1652 chipname = "PCnet/32 79C965"; /* 486/VL bus */
1653 break;
1654 case 0x2621:
1655 chipname = "PCnet/PCI II 79C970A"; /* PCI */
1656 fdx = 1;
1657 break;
1658 case 0x2623:
1659 chipname = "PCnet/FAST 79C971"; /* PCI */
1660 fdx = 1;
1661 mii = 1;
1662 fset = 1;
1663 break;
1664 case 0x2624:
1665 chipname = "PCnet/FAST+ 79C972"; /* PCI */
1666 fdx = 1;
1667 mii = 1;
1668 fset = 1;
1669 break;
1670 case 0x2625:
1671 chipname = "PCnet/FAST III 79C973"; /* PCI */
1672 fdx = 1;
1673 mii = 1;
Markos Chandras87f966d2015-03-19 10:28:14 +00001674 sram = 1;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001675 break;
1676 case 0x2626:
1677 chipname = "PCnet/Home 79C978"; /* PCI */
1678 fdx = 1;
1679 /*
1680 * This is based on specs published at www.amd.com. This section
1681 * assumes that a card with a 79C978 wants to go into standard
1682 * ethernet mode. The 79C978 can also go into 1Mb HomePNA mode,
1683 * and the module option homepna=1 can select this instead.
1684 */
1685 media = a->read_bcr(ioaddr, 49);
1686 media &= ~3; /* default to 10Mb ethernet */
1687 if (cards_found < MAX_UNITS && homepna[cards_found])
1688 media |= 1; /* switch to home wiring mode */
1689 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001690 printk(KERN_DEBUG PFX "media set to %sMbit mode\n",
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001691 (media & 1) ? "1" : "10");
1692 a->write_bcr(ioaddr, 49, media);
1693 break;
1694 case 0x2627:
1695 chipname = "PCnet/FAST III 79C975"; /* PCI */
1696 fdx = 1;
1697 mii = 1;
Markos Chandras87f966d2015-03-19 10:28:14 +00001698 sram = 1;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001699 break;
1700 case 0x2628:
1701 chipname = "PCnet/PRO 79C976";
1702 fdx = 1;
1703 mii = 1;
1704 break;
1705 default:
1706 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001707 pr_info("PCnet version %#x, no PCnet32 chip\n",
1708 chip_version);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001709 goto err_release_region;
1710 }
1711
1712 /*
1713 * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit
1714 * starting until the packet is loaded. Strike one for reliability, lose
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001715 * one for latency - although on PCI this isn't a big loss. Older chips
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001716 * have FIFO's smaller than a packet, so you can't do this.
1717 * Turn on BCR18:BurstRdEn and BCR18:BurstWrEn.
1718 */
1719
1720 if (fset) {
1721 a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0860));
1722 a->write_csr(ioaddr, 80,
1723 (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00);
1724 dxsuflo = 1;
1725 }
1726
Markos Chandras87f966d2015-03-19 10:28:14 +00001727 /*
1728 * The Am79C973/Am79C975 controllers come with 12K of SRAM
1729 * which we can use for the Tx/Rx buffers but most importantly,
1730 * the use of SRAM allow us to use the BCR18:NOUFLO bit to avoid
1731 * Tx fifo underflows.
1732 */
1733 if (sram) {
1734 /*
1735 * The SRAM is being configured in two steps. First we
1736 * set the SRAM size in the BCR25:SRAM_SIZE bits. According
1737 * to the datasheet, each bit corresponds to a 512-byte
1738 * page so we can have at most 24 pages. The SRAM_SIZE
1739 * holds the value of the upper 8 bits of the 16-bit SRAM size.
1740 * The low 8-bits start at 0x00 and end at 0xff. So the
1741 * address range is from 0x0000 up to 0x17ff. Therefore,
1742 * the SRAM_SIZE is set to 0x17. The next step is to set
1743 * the BCR26:SRAM_BND midway through so the Tx and Rx
1744 * buffers can share the SRAM equally.
1745 */
1746 a->write_bcr(ioaddr, 25, 0x17);
1747 a->write_bcr(ioaddr, 26, 0xc);
1748 /* And finally enable the NOUFLO bit */
1749 a->write_bcr(ioaddr, 18, a->read_bcr(ioaddr, 18) | (1 << 11));
1750 }
1751
Don Fry6ecb7662007-03-06 10:45:23 -08001752 dev = alloc_etherdev(sizeof(*lp));
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001753 if (!dev) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001754 ret = -ENOMEM;
1755 goto err_release_region;
1756 }
Don Fry63097b32009-07-31 08:45:29 +00001757
1758 if (pdev)
1759 SET_NETDEV_DEV(dev, &pdev->dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001760
1761 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001762 pr_info("%s at %#3lx,", chipname, ioaddr);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001763
1764 /* In most chips, after a chip reset, the ethernet address is read from the
1765 * station address PROM at the base address and programmed into the
1766 * "Physical Address Registers" CSR12-14.
1767 * As a precautionary measure, we read the PROM values and complain if
Linas Vepstasbc0e1fc2006-03-28 16:36:23 -06001768 * they disagree with the CSRs. If they miscompare, and the PROM addr
1769 * is valid, then the PROM addr is used.
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001770 */
1771 for (i = 0; i < 3; i++) {
1772 unsigned int val;
1773 val = a->read_csr(ioaddr, i + 12) & 0x0ffff;
1774 /* There may be endianness issues here. */
1775 dev->dev_addr[2 * i] = val & 0x0ff;
1776 dev->dev_addr[2 * i + 1] = (val >> 8) & 0x0ff;
1777 }
1778
1779 /* read PROM address and compare with CSR address */
Joe Perches1409a932013-08-01 16:17:49 -07001780 for (i = 0; i < ETH_ALEN; i++)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001781 promaddr[i] = inb(ioaddr + i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782
dingtianhongebff7b42013-12-26 19:40:22 +08001783 if (!ether_addr_equal(promaddr, dev->dev_addr) ||
Joe Perches8e95a202009-12-03 07:58:21 +00001784 !is_valid_ether_addr(dev->dev_addr)) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001785 if (is_valid_ether_addr(promaddr)) {
1786 if (pcnet32_debug & NETIF_MSG_PROBE) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001787 pr_cont(" warning: CSR address invalid,\n");
1788 pr_info(" using instead PROM address of");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001789 }
Joe Perchesd458cdf2013-10-01 19:04:40 -07001790 memcpy(dev->dev_addr, promaddr, ETH_ALEN);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001791 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001794 /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
Jiri Pirkoaaeb6cd2013-01-08 01:38:26 +00001795 if (!is_valid_ether_addr(dev->dev_addr))
Joe Perchesc7bf7162015-03-02 19:54:47 -08001796 eth_zero_addr(dev->dev_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001798 if (pcnet32_debug & NETIF_MSG_PROBE) {
Joe Perches13ff83b2010-02-15 08:34:25 +00001799 pr_cont(" %pM", dev->dev_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001801 /* Version 0x2623 and 0x2624 */
1802 if (((chip_version + 1) & 0xfffe) == 0x2624) {
1803 i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */
Joe Perches13ff83b2010-02-15 08:34:25 +00001804 pr_info(" tx_start_pt(0x%04x):", i);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001805 switch (i >> 10) {
1806 case 0:
Joe Perches13ff83b2010-02-15 08:34:25 +00001807 pr_cont(" 20 bytes,");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001808 break;
1809 case 1:
Joe Perches13ff83b2010-02-15 08:34:25 +00001810 pr_cont(" 64 bytes,");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001811 break;
1812 case 2:
Joe Perches13ff83b2010-02-15 08:34:25 +00001813 pr_cont(" 128 bytes,");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001814 break;
1815 case 3:
Joe Perches13ff83b2010-02-15 08:34:25 +00001816 pr_cont("~220 bytes,");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001817 break;
1818 }
1819 i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */
Joe Perches13ff83b2010-02-15 08:34:25 +00001820 pr_cont(" BCR18(%x):", i & 0xffff);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001821 if (i & (1 << 5))
Joe Perches13ff83b2010-02-15 08:34:25 +00001822 pr_cont("BurstWrEn ");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001823 if (i & (1 << 6))
Joe Perches13ff83b2010-02-15 08:34:25 +00001824 pr_cont("BurstRdEn ");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001825 if (i & (1 << 7))
Joe Perches13ff83b2010-02-15 08:34:25 +00001826 pr_cont("DWordIO ");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001827 if (i & (1 << 11))
Joe Perches13ff83b2010-02-15 08:34:25 +00001828 pr_cont("NoUFlow ");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001829 i = a->read_bcr(ioaddr, 25);
Joe Perches13ff83b2010-02-15 08:34:25 +00001830 pr_info(" SRAMSIZE=0x%04x,", i << 8);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001831 i = a->read_bcr(ioaddr, 26);
Joe Perches13ff83b2010-02-15 08:34:25 +00001832 pr_cont(" SRAM_BND=0x%04x,", i << 8);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001833 i = a->read_bcr(ioaddr, 27);
1834 if (i & (1 << 14))
Joe Perches13ff83b2010-02-15 08:34:25 +00001835 pr_cont("LowLatRx");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001836 }
1837 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001839 dev->base_addr = ioaddr;
Don Fry1e56a4b2007-03-06 10:55:00 -08001840 lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001841 /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
Joe Perches9e3f8062010-02-15 08:34:26 +00001842 lp->init_block = pci_alloc_consistent(pdev, sizeof(*lp->init_block),
1843 &lp->init_dma_addr);
1844 if (!lp->init_block) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001845 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001846 pr_err("Consistent memory allocation failed\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001847 ret = -ENOMEM;
1848 goto err_free_netdev;
1849 }
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001850 lp->pci_dev = pdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001852 lp->dev = dev;
1853
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001854 spin_lock_init(&lp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001856 lp->name = chipname;
1857 lp->shared_irq = shared;
1858 lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */
1859 lp->rx_ring_size = RX_RING_SIZE; /* default rx ring size */
1860 lp->tx_mod_mask = lp->tx_ring_size - 1;
1861 lp->rx_mod_mask = lp->rx_ring_size - 1;
1862 lp->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 12);
1863 lp->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4);
1864 lp->mii_if.full_duplex = fdx;
1865 lp->mii_if.phy_id_mask = 0x1f;
1866 lp->mii_if.reg_num_mask = 0x1f;
1867 lp->dxsuflo = dxsuflo;
1868 lp->mii = mii;
Don Fry8d916262006-08-22 10:22:37 -07001869 lp->chip_version = chip_version;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001870 lp->msg_enable = pcnet32_debug;
Joe Perches8e95a202009-12-03 07:58:21 +00001871 if ((cards_found >= MAX_UNITS) ||
1872 (options[cards_found] >= sizeof(options_mapping)))
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001873 lp->options = PCNET32_PORT_ASEL;
1874 else
1875 lp->options = options_mapping[options[cards_found]];
Ondrej Zary2be4cb92017-02-13 23:45:47 +01001876 /* force default port to TP on 79C970A so link detection can work */
1877 if (lp->chip_version == PCNET32_79C970A)
1878 lp->options = PCNET32_PORT_10BT;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001879 lp->mii_if.dev = dev;
1880 lp->mii_if.mdio_read = mdio_read;
1881 lp->mii_if.mdio_write = mdio_write;
1882
Don Fryfeff3482007-10-17 15:59:22 -07001883 /* napi.weight is used in both the napi and non-napi cases */
1884 lp->napi.weight = lp->rx_ring_size / 2;
1885
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001886 netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2);
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001887
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001888 if (fdx && !(lp->options & PCNET32_PORT_ASEL) &&
1889 ((cards_found >= MAX_UNITS) || full_duplex[cards_found]))
1890 lp->options |= PCNET32_PORT_FD;
1891
stephen hemminger1d70cb02011-09-16 11:06:26 +00001892 lp->a = a;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001893
1894 /* prior to register_netdev, dev->name is not yet correct */
1895 if (pcnet32_alloc_ring(dev, pci_name(lp->pci_dev))) {
1896 ret = -ENOMEM;
1897 goto err_free_ring;
1898 }
1899 /* detect special T1/E1 WAN card by checking for MAC address */
Joe Perches8e95a202009-12-03 07:58:21 +00001900 if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 &&
1901 dev->dev_addr[2] == 0x75)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001902 lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903
Al Viro3e335452007-08-23 00:45:46 -04001904 lp->init_block->mode = cpu_to_le16(0x0003); /* Disable Rx and Tx. */
Don Fry6ecb7662007-03-06 10:45:23 -08001905 lp->init_block->tlen_rlen =
Al Viro3e335452007-08-23 00:45:46 -04001906 cpu_to_le16(lp->tx_len_bits | lp->rx_len_bits);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001907 for (i = 0; i < 6; i++)
Don Fry6ecb7662007-03-06 10:45:23 -08001908 lp->init_block->phys_addr[i] = dev->dev_addr[i];
1909 lp->init_block->filter[0] = 0x00000000;
1910 lp->init_block->filter[1] = 0x00000000;
Al Viro3e335452007-08-23 00:45:46 -04001911 lp->init_block->rx_ring = cpu_to_le32(lp->rx_ring_dma_addr);
1912 lp->init_block->tx_ring = cpu_to_le32(lp->tx_ring_dma_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001914 /* switch pcnet32 to 32bit mode */
1915 a->write_bcr(ioaddr, 20, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916
Don Fry6ecb7662007-03-06 10:45:23 -08001917 a->write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
1918 a->write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001920 if (pdev) { /* use the IRQ provided by PCI */
1921 dev->irq = pdev->irq;
1922 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001923 pr_cont(" assigned IRQ %d\n", dev->irq);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001924 } else {
1925 unsigned long irq_mask = probe_irq_on();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001927 /*
1928 * To auto-IRQ we enable the initialization-done and DMA error
1929 * interrupts. For ISA boards we get a DMA error, but VLB and PCI
1930 * boards will work.
1931 */
1932 /* Trigger an initialization just for the interrupt. */
Don Fryb368a3f2006-09-13 10:16:07 -07001933 a->write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_INIT);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001934 mdelay(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001936 dev->irq = probe_irq_off(irq_mask);
1937 if (!dev->irq) {
1938 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001939 pr_cont(", failed to detect IRQ line\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001940 ret = -ENODEV;
1941 goto err_free_ring;
1942 }
1943 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001944 pr_cont(", probed IRQ %d\n", dev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001947 /* Set the mii phy_id so that we can query the link state */
1948 if (lp->mii) {
1949 /* lp->phycount and lp->phymask are set to 0 by memset above */
Don Fryac62ef02006-03-20 15:26:03 -08001950
stephen hemminger1d70cb02011-09-16 11:06:26 +00001951 lp->mii_if.phy_id = ((lp->a->read_bcr(ioaddr, 33)) >> 5) & 0x1f;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001952 /* scan for PHYs */
1953 for (i = 0; i < PCNET32_MAX_PHYS; i++) {
1954 unsigned short id1, id2;
Don Fryac62ef02006-03-20 15:26:03 -08001955
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001956 id1 = mdio_read(dev, i, MII_PHYSID1);
1957 if (id1 == 0xffff)
1958 continue;
1959 id2 = mdio_read(dev, i, MII_PHYSID2);
1960 if (id2 == 0xffff)
1961 continue;
1962 if (i == 31 && ((chip_version + 1) & 0xfffe) == 0x2624)
1963 continue; /* 79C971 & 79C972 have phantom phy at id 31 */
1964 lp->phycount++;
1965 lp->phymask |= (1 << i);
1966 lp->mii_if.phy_id = i;
1967 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001968 pr_info("Found PHY %04x:%04x at address %d\n",
1969 id1, id2, i);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001970 }
stephen hemminger1d70cb02011-09-16 11:06:26 +00001971 lp->a->write_bcr(ioaddr, 33, (lp->mii_if.phy_id) << 5);
Joe Perches9e3f8062010-02-15 08:34:26 +00001972 if (lp->phycount > 1)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001973 lp->options |= PCNET32_PORT_MII;
Don Fryac62ef02006-03-20 15:26:03 -08001974 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001976 init_timer(&lp->watchdog_timer);
1977 lp->watchdog_timer.data = (unsigned long)dev;
1978 lp->watchdog_timer.function = (void *)&pcnet32_watchdog;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001980 /* The PCNET32-specific entries in the device structure. */
Stephen Hemminger3bc124d2009-01-07 17:29:16 -08001981 dev->netdev_ops = &pcnet32_netdev_ops;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001982 dev->ethtool_ops = &pcnet32_ethtool_ops;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001983 dev->watchdog_timeo = (5 * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001985 /* Fill in the generic fields of the device structure. */
1986 if (register_netdev(dev))
1987 goto err_free_ring;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001989 if (pdev) {
1990 pci_set_drvdata(pdev, dev);
1991 } else {
1992 lp->next = pcnet32_dev;
1993 pcnet32_dev = dev;
1994 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001996 if (pcnet32_debug & NETIF_MSG_PROBE)
Joe Perches13ff83b2010-02-15 08:34:25 +00001997 pr_info("%s: registered as %s\n", dev->name, lp->name);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05001998 cards_found++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002000 /* enable LED writes */
2001 a->write_bcr(ioaddr, 2, a->read_bcr(ioaddr, 2) | 0x1000);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002003 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004
Don Frydf4e7f72009-07-31 08:40:06 +00002005err_free_ring:
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002006 pcnet32_free_ring(dev);
Jeff Garzik7d2e3cb2008-05-13 01:41:58 -04002007 pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
Don Fry6ecb7662007-03-06 10:45:23 -08002008 lp->init_block, lp->init_dma_addr);
Don Frydf4e7f72009-07-31 08:40:06 +00002009err_free_netdev:
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002010 free_netdev(dev);
Don Frydf4e7f72009-07-31 08:40:06 +00002011err_release_region:
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002012 release_region(ioaddr, PCNET32_TOTAL_SIZE);
2013 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014}
2015
Don Frya88c8442005-11-01 12:04:33 -08002016/* if any allocation fails, caller must also call pcnet32_free_ring */
Andrew Mortonb166cfb2008-05-14 16:20:14 -07002017static int pcnet32_alloc_ring(struct net_device *dev, const char *name)
Hubert WS Lineabf0412005-09-14 11:39:25 -07002018{
Don Fry1e56a4b2007-03-06 10:55:00 -08002019 struct pcnet32_private *lp = netdev_priv(dev);
Hubert WS Lineabf0412005-09-14 11:39:25 -07002020
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002021 lp->tx_ring = pci_alloc_consistent(lp->pci_dev,
2022 sizeof(struct pcnet32_tx_head) *
2023 lp->tx_ring_size,
2024 &lp->tx_ring_dma_addr);
2025 if (lp->tx_ring == NULL) {
Joe Perches13ff83b2010-02-15 08:34:25 +00002026 netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002027 return -ENOMEM;
2028 }
Hubert WS Lineabf0412005-09-14 11:39:25 -07002029
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002030 lp->rx_ring = pci_alloc_consistent(lp->pci_dev,
2031 sizeof(struct pcnet32_rx_head) *
2032 lp->rx_ring_size,
2033 &lp->rx_ring_dma_addr);
2034 if (lp->rx_ring == NULL) {
Joe Perches13ff83b2010-02-15 08:34:25 +00002035 netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002036 return -ENOMEM;
2037 }
Hubert WS Lineabf0412005-09-14 11:39:25 -07002038
Don Fry12fa30f2006-06-29 13:53:48 -07002039 lp->tx_dma_addr = kcalloc(lp->tx_ring_size, sizeof(dma_addr_t),
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002040 GFP_ATOMIC);
Joe Perches14f8dc42013-02-07 11:46:27 +00002041 if (!lp->tx_dma_addr)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002042 return -ENOMEM;
Hubert WS Lineabf0412005-09-14 11:39:25 -07002043
Don Fry12fa30f2006-06-29 13:53:48 -07002044 lp->rx_dma_addr = kcalloc(lp->rx_ring_size, sizeof(dma_addr_t),
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002045 GFP_ATOMIC);
Joe Perches14f8dc42013-02-07 11:46:27 +00002046 if (!lp->rx_dma_addr)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002047 return -ENOMEM;
Hubert WS Lineabf0412005-09-14 11:39:25 -07002048
Don Fry12fa30f2006-06-29 13:53:48 -07002049 lp->tx_skbuff = kcalloc(lp->tx_ring_size, sizeof(struct sk_buff *),
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002050 GFP_ATOMIC);
Joe Perches14f8dc42013-02-07 11:46:27 +00002051 if (!lp->tx_skbuff)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002052 return -ENOMEM;
Hubert WS Lineabf0412005-09-14 11:39:25 -07002053
Don Fry12fa30f2006-06-29 13:53:48 -07002054 lp->rx_skbuff = kcalloc(lp->rx_ring_size, sizeof(struct sk_buff *),
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002055 GFP_ATOMIC);
Joe Perches14f8dc42013-02-07 11:46:27 +00002056 if (!lp->rx_skbuff)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002057 return -ENOMEM;
Hubert WS Lineabf0412005-09-14 11:39:25 -07002058
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002059 return 0;
Hubert WS Lineabf0412005-09-14 11:39:25 -07002060}
2061
Hubert WS Lineabf0412005-09-14 11:39:25 -07002062static void pcnet32_free_ring(struct net_device *dev)
2063{
Don Fry1e56a4b2007-03-06 10:55:00 -08002064 struct pcnet32_private *lp = netdev_priv(dev);
Hubert WS Lineabf0412005-09-14 11:39:25 -07002065
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002066 kfree(lp->tx_skbuff);
2067 lp->tx_skbuff = NULL;
Hubert WS Lineabf0412005-09-14 11:39:25 -07002068
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002069 kfree(lp->rx_skbuff);
2070 lp->rx_skbuff = NULL;
Hubert WS Lineabf0412005-09-14 11:39:25 -07002071
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002072 kfree(lp->tx_dma_addr);
2073 lp->tx_dma_addr = NULL;
Hubert WS Lineabf0412005-09-14 11:39:25 -07002074
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002075 kfree(lp->rx_dma_addr);
2076 lp->rx_dma_addr = NULL;
Hubert WS Lineabf0412005-09-14 11:39:25 -07002077
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002078 if (lp->tx_ring) {
2079 pci_free_consistent(lp->pci_dev,
2080 sizeof(struct pcnet32_tx_head) *
2081 lp->tx_ring_size, lp->tx_ring,
2082 lp->tx_ring_dma_addr);
2083 lp->tx_ring = NULL;
2084 }
Hubert WS Lineabf0412005-09-14 11:39:25 -07002085
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002086 if (lp->rx_ring) {
2087 pci_free_consistent(lp->pci_dev,
2088 sizeof(struct pcnet32_rx_head) *
2089 lp->rx_ring_size, lp->rx_ring,
2090 lp->rx_ring_dma_addr);
2091 lp->rx_ring = NULL;
2092 }
Hubert WS Lineabf0412005-09-14 11:39:25 -07002093}
2094
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002095static int pcnet32_open(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096{
Don Fry1e56a4b2007-03-06 10:55:00 -08002097 struct pcnet32_private *lp = netdev_priv(dev);
Don Fry63097b32009-07-31 08:45:29 +00002098 struct pci_dev *pdev = lp->pci_dev;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002099 unsigned long ioaddr = dev->base_addr;
2100 u16 val;
2101 int i;
2102 int rc;
2103 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104
Joe Perchesa0607fd2009-11-18 23:29:17 -08002105 if (request_irq(dev->irq, pcnet32_interrupt,
Thomas Gleixner1fb9df52006-07-01 19:29:39 -07002106 lp->shared_irq ? IRQF_SHARED : 0, dev->name,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002107 (void *)dev)) {
2108 return -EAGAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002111 spin_lock_irqsave(&lp->lock, flags);
2112 /* Check for a valid station address */
2113 if (!is_valid_ether_addr(dev->dev_addr)) {
2114 rc = -EINVAL;
2115 goto err_free_irq;
2116 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002118 /* Reset the PCNET32 */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002119 lp->a->reset(ioaddr);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002120
2121 /* switch pcnet32 to 32bit mode */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002122 lp->a->write_bcr(ioaddr, 20, 2);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002123
Joe Perches13ff83b2010-02-15 08:34:25 +00002124 netif_printk(lp, ifup, KERN_DEBUG, dev,
2125 "%s() irq %d tx/rx rings %#x/%#x init %#x\n",
2126 __func__, dev->irq, (u32) (lp->tx_ring_dma_addr),
2127 (u32) (lp->rx_ring_dma_addr),
2128 (u32) (lp->init_dma_addr));
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002129
Ondrej Zary2be4cb92017-02-13 23:45:47 +01002130 lp->autoneg = !!(lp->options & PCNET32_PORT_ASEL);
2131 lp->port_tp = !!(lp->options & PCNET32_PORT_10BT);
2132 lp->fdx = !!(lp->options & PCNET32_PORT_FD);
2133
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002134 /* set/reset autoselect bit */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002135 val = lp->a->read_bcr(ioaddr, 2) & ~2;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002136 if (lp->options & PCNET32_PORT_ASEL)
2137 val |= 2;
stephen hemminger1d70cb02011-09-16 11:06:26 +00002138 lp->a->write_bcr(ioaddr, 2, val);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002139
2140 /* handle full duplex setting */
2141 if (lp->mii_if.full_duplex) {
stephen hemminger1d70cb02011-09-16 11:06:26 +00002142 val = lp->a->read_bcr(ioaddr, 9) & ~3;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002143 if (lp->options & PCNET32_PORT_FD) {
2144 val |= 1;
2145 if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI))
2146 val |= 2;
2147 } else if (lp->options & PCNET32_PORT_ASEL) {
2148 /* workaround of xSeries250, turn on for 79C975 only */
Don Fry8d916262006-08-22 10:22:37 -07002149 if (lp->chip_version == 0x2627)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002150 val |= 3;
2151 }
stephen hemminger1d70cb02011-09-16 11:06:26 +00002152 lp->a->write_bcr(ioaddr, 9, val);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002153 }
2154
2155 /* set/reset GPSI bit in test register */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002156 val = lp->a->read_csr(ioaddr, 124) & ~0x10;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002157 if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI)
2158 val |= 0x10;
stephen hemminger1d70cb02011-09-16 11:06:26 +00002159 lp->a->write_csr(ioaddr, 124, val);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002160
2161 /* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not negotiate */
Don Fry63097b32009-07-31 08:45:29 +00002162 if (pdev && pdev->subsystem_vendor == PCI_VENDOR_ID_AT &&
2163 (pdev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
2164 pdev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
Don Fryac62ef02006-03-20 15:26:03 -08002165 if (lp->options & PCNET32_PORT_ASEL) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002166 lp->options = PCNET32_PORT_FD | PCNET32_PORT_100;
Joe Perches13ff83b2010-02-15 08:34:25 +00002167 netif_printk(lp, link, KERN_DEBUG, dev,
2168 "Setting 100Mb-Full Duplex\n");
Don Fryac62ef02006-03-20 15:26:03 -08002169 }
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002170 }
2171 if (lp->phycount < 2) {
2172 /*
2173 * 24 Jun 2004 according AMD, in order to change the PHY,
2174 * DANAS (or DISPM for 79C976) must be set; then select the speed,
2175 * duplex, and/or enable auto negotiation, and clear DANAS
2176 */
2177 if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
stephen hemminger1d70cb02011-09-16 11:06:26 +00002178 lp->a->write_bcr(ioaddr, 32,
2179 lp->a->read_bcr(ioaddr, 32) | 0x0080);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002180 /* disable Auto Negotiation, set 10Mpbs, HD */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002181 val = lp->a->read_bcr(ioaddr, 32) & ~0xb8;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002182 if (lp->options & PCNET32_PORT_FD)
2183 val |= 0x10;
2184 if (lp->options & PCNET32_PORT_100)
2185 val |= 0x08;
stephen hemminger1d70cb02011-09-16 11:06:26 +00002186 lp->a->write_bcr(ioaddr, 32, val);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002187 } else {
2188 if (lp->options & PCNET32_PORT_ASEL) {
stephen hemminger1d70cb02011-09-16 11:06:26 +00002189 lp->a->write_bcr(ioaddr, 32,
2190 lp->a->read_bcr(ioaddr,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002191 32) | 0x0080);
2192 /* enable auto negotiate, setup, disable fd */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002193 val = lp->a->read_bcr(ioaddr, 32) & ~0x98;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002194 val |= 0x20;
stephen hemminger1d70cb02011-09-16 11:06:26 +00002195 lp->a->write_bcr(ioaddr, 32, val);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002196 }
2197 }
2198 } else {
2199 int first_phy = -1;
2200 u16 bmcr;
2201 u32 bcr9;
David Decotigny8ae6daca2011-04-27 18:32:38 +00002202 struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002203
2204 /*
2205 * There is really no good other way to handle multiple PHYs
2206 * other than turning off all automatics
2207 */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002208 val = lp->a->read_bcr(ioaddr, 2);
2209 lp->a->write_bcr(ioaddr, 2, val & ~2);
2210 val = lp->a->read_bcr(ioaddr, 32);
2211 lp->a->write_bcr(ioaddr, 32, val & ~(1 << 7)); /* stop MII manager */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002212
2213 if (!(lp->options & PCNET32_PORT_ASEL)) {
2214 /* setup ecmd */
2215 ecmd.port = PORT_MII;
2216 ecmd.transceiver = XCVR_INTERNAL;
2217 ecmd.autoneg = AUTONEG_DISABLE;
David Decotigny8ae6daca2011-04-27 18:32:38 +00002218 ethtool_cmd_speed_set(&ecmd,
2219 (lp->options & PCNET32_PORT_100) ?
2220 SPEED_100 : SPEED_10);
stephen hemminger1d70cb02011-09-16 11:06:26 +00002221 bcr9 = lp->a->read_bcr(ioaddr, 9);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002222
2223 if (lp->options & PCNET32_PORT_FD) {
2224 ecmd.duplex = DUPLEX_FULL;
2225 bcr9 |= (1 << 0);
2226 } else {
2227 ecmd.duplex = DUPLEX_HALF;
2228 bcr9 |= ~(1 << 0);
2229 }
stephen hemminger1d70cb02011-09-16 11:06:26 +00002230 lp->a->write_bcr(ioaddr, 9, bcr9);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002231 }
2232
2233 for (i = 0; i < PCNET32_MAX_PHYS; i++) {
2234 if (lp->phymask & (1 << i)) {
2235 /* isolate all but the first PHY */
2236 bmcr = mdio_read(dev, i, MII_BMCR);
2237 if (first_phy == -1) {
2238 first_phy = i;
2239 mdio_write(dev, i, MII_BMCR,
2240 bmcr & ~BMCR_ISOLATE);
2241 } else {
2242 mdio_write(dev, i, MII_BMCR,
2243 bmcr | BMCR_ISOLATE);
2244 }
2245 /* use mii_ethtool_sset to setup PHY */
2246 lp->mii_if.phy_id = i;
2247 ecmd.phy_address = i;
2248 if (lp->options & PCNET32_PORT_ASEL) {
2249 mii_ethtool_gset(&lp->mii_if, &ecmd);
2250 ecmd.autoneg = AUTONEG_ENABLE;
2251 }
2252 mii_ethtool_sset(&lp->mii_if, &ecmd);
2253 }
2254 }
2255 lp->mii_if.phy_id = first_phy;
Joe Perches13ff83b2010-02-15 08:34:25 +00002256 netif_info(lp, link, dev, "Using PHY number %d\n", first_phy);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002257 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258
2259#ifdef DO_DXSUFLO
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002260 if (lp->dxsuflo) { /* Disable transmit stop on underflow */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002261 val = lp->a->read_csr(ioaddr, CSR3);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002262 val |= 0x40;
stephen hemminger1d70cb02011-09-16 11:06:26 +00002263 lp->a->write_csr(ioaddr, CSR3, val);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002264 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265#endif
2266
Don Fry6ecb7662007-03-06 10:45:23 -08002267 lp->init_block->mode =
Al Viro3e335452007-08-23 00:45:46 -04002268 cpu_to_le16((lp->options & PCNET32_PORT_PORTSEL) << 7);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002269 pcnet32_load_multicast(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002271 if (pcnet32_init_ring(dev)) {
2272 rc = -ENOMEM;
2273 goto err_free_ring;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274 }
Hubert WS Lineabf0412005-09-14 11:39:25 -07002275
Stephen Hemmingerbea33482007-10-03 16:41:36 -07002276 napi_enable(&lp->napi);
Stephen Hemmingerbea33482007-10-03 16:41:36 -07002277
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002278 /* Re-initialize the PCNET32, and start it when done. */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002279 lp->a->write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
2280 lp->a->write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
Hubert WS Lineabf0412005-09-14 11:39:25 -07002281
stephen hemminger1d70cb02011-09-16 11:06:26 +00002282 lp->a->write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
2283 lp->a->write_csr(ioaddr, CSR0, CSR0_INIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002285 netif_start_queue(dev);
2286
Don Fry8d916262006-08-22 10:22:37 -07002287 if (lp->chip_version >= PCNET32_79C970A) {
2288 /* Print the link status and start the watchdog */
2289 pcnet32_check_media(dev, 1);
Stephen Hemminger283a21d32009-01-08 11:17:13 -08002290 mod_timer(&lp->watchdog_timer, PCNET32_WATCHDOG_TIMEOUT);
Don Fry8d916262006-08-22 10:22:37 -07002291 }
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002292
2293 i = 0;
2294 while (i++ < 100)
stephen hemminger1d70cb02011-09-16 11:06:26 +00002295 if (lp->a->read_csr(ioaddr, CSR0) & CSR0_IDON)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002296 break;
2297 /*
2298 * We used to clear the InitDone bit, 0x0100, here but Mark Stockton
2299 * reports that doing so triggers a bug in the '974.
2300 */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002301 lp->a->write_csr(ioaddr, CSR0, CSR0_NORMAL);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002302
Joe Perches13ff83b2010-02-15 08:34:25 +00002303 netif_printk(lp, ifup, KERN_DEBUG, dev,
2304 "pcnet32 open after %d ticks, init block %#x csr0 %4.4x\n",
2305 i,
2306 (u32) (lp->init_dma_addr),
stephen hemminger1d70cb02011-09-16 11:06:26 +00002307 lp->a->read_csr(ioaddr, CSR0));
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002308
2309 spin_unlock_irqrestore(&lp->lock, flags);
2310
2311 return 0; /* Always succeed */
2312
Joe Perches9e3f8062010-02-15 08:34:26 +00002313err_free_ring:
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002314 /* free any allocated skbuffs */
Don Fryac5bfe42006-06-29 13:55:27 -07002315 pcnet32_purge_rx_ring(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002316
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002317 /*
2318 * Switch back to 16bit mode to avoid problems with dumb
2319 * DOS packet driver after a warm reboot
2320 */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002321 lp->a->write_bcr(ioaddr, 20, 4);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002322
Joe Perches9e3f8062010-02-15 08:34:26 +00002323err_free_irq:
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002324 spin_unlock_irqrestore(&lp->lock, flags);
2325 free_irq(dev->irq, dev);
2326 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327}
2328
2329/*
2330 * The LANCE has been halted for one reason or another (busmaster memory
2331 * arbitration error, Tx FIFO underflow, driver stopped it to reconfigure,
2332 * etc.). Modern LANCE variants always reload their ring-buffer
2333 * configuration when restarted, so we must reinitialize our ring
2334 * context before restarting. As part of this reinitialization,
2335 * find all packets still on the Tx ring and pretend that they had been
2336 * sent (in effect, drop the packets on the floor) - the higher-level
2337 * protocols will time out and retransmit. It'd be better to shuffle
2338 * these skbs to a temp list and then actually re-Tx them after
2339 * restarting the chip, but I'm too lazy to do so right now. dplatt@3do.com
2340 */
2341
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002342static void pcnet32_purge_tx_ring(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002343{
Don Fry1e56a4b2007-03-06 10:55:00 -08002344 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002345 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002347 for (i = 0; i < lp->tx_ring_size; i++) {
2348 lp->tx_ring[i].status = 0; /* CPU owns buffer */
2349 wmb(); /* Make sure adapter sees owner change */
2350 if (lp->tx_skbuff[i]) {
Don Fry4cc5c472014-02-17 20:57:59 -08002351 if (!pci_dma_mapping_error(lp->pci_dev,
2352 lp->tx_dma_addr[i]))
2353 pci_unmap_single(lp->pci_dev,
2354 lp->tx_dma_addr[i],
2355 lp->tx_skbuff[i]->len,
2356 PCI_DMA_TODEVICE);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002357 dev_kfree_skb_any(lp->tx_skbuff[i]);
2358 }
2359 lp->tx_skbuff[i] = NULL;
2360 lp->tx_dma_addr[i] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362}
2363
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364/* Initialize the PCNET32 Rx and Tx rings. */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002365static int pcnet32_init_ring(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366{
Don Fry1e56a4b2007-03-06 10:55:00 -08002367 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002368 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002369
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002370 lp->tx_full = 0;
2371 lp->cur_rx = lp->cur_tx = 0;
2372 lp->dirty_rx = lp->dirty_tx = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002374 for (i = 0; i < lp->rx_ring_size; i++) {
2375 struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
2376 if (rx_skbuff == NULL) {
Pradeep A Dalvi1d266432012-02-05 02:49:09 +00002377 lp->rx_skbuff[i] = netdev_alloc_skb(dev, PKT_BUF_SKB);
Joe Perches9e3f8062010-02-15 08:34:26 +00002378 rx_skbuff = lp->rx_skbuff[i];
2379 if (!rx_skbuff) {
2380 /* there is not much we can do at this point */
Pradeep A Dalvi1d266432012-02-05 02:49:09 +00002381 netif_err(lp, drv, dev, "%s netdev_alloc_skb failed\n",
Joe Perches13ff83b2010-02-15 08:34:25 +00002382 __func__);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002383 return -1;
2384 }
Don Fry232c5642008-02-08 07:32:26 -08002385 skb_reserve(rx_skbuff, NET_IP_ALIGN);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002386 }
2387
2388 rmb();
Don Fry4cc5c472014-02-17 20:57:59 -08002389 if (lp->rx_dma_addr[i] == 0) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002390 lp->rx_dma_addr[i] =
2391 pci_map_single(lp->pci_dev, rx_skbuff->data,
Don Fry232c5642008-02-08 07:32:26 -08002392 PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
Don Fry4cc5c472014-02-17 20:57:59 -08002393 if (pci_dma_mapping_error(lp->pci_dev,
2394 lp->rx_dma_addr[i])) {
2395 /* there is not much we can do at this point */
2396 netif_err(lp, drv, dev,
2397 "%s pci dma mapping error\n",
2398 __func__);
2399 return -1;
2400 }
2401 }
Al Viro3e335452007-08-23 00:45:46 -04002402 lp->rx_ring[i].base = cpu_to_le32(lp->rx_dma_addr[i]);
Don Fry232c5642008-02-08 07:32:26 -08002403 lp->rx_ring[i].buf_length = cpu_to_le16(NEG_BUF_SIZE);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002404 wmb(); /* Make sure owner changes after all others are visible */
Al Viro3e335452007-08-23 00:45:46 -04002405 lp->rx_ring[i].status = cpu_to_le16(0x8000);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002406 }
2407 /* The Tx buffer address is filled in as needed, but we do need to clear
2408 * the upper ownership bit. */
2409 for (i = 0; i < lp->tx_ring_size; i++) {
2410 lp->tx_ring[i].status = 0; /* CPU owns buffer */
2411 wmb(); /* Make sure adapter sees owner change */
2412 lp->tx_ring[i].base = 0;
2413 lp->tx_dma_addr[i] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 }
2415
Don Fry6ecb7662007-03-06 10:45:23 -08002416 lp->init_block->tlen_rlen =
Al Viro3e335452007-08-23 00:45:46 -04002417 cpu_to_le16(lp->tx_len_bits | lp->rx_len_bits);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002418 for (i = 0; i < 6; i++)
Don Fry6ecb7662007-03-06 10:45:23 -08002419 lp->init_block->phys_addr[i] = dev->dev_addr[i];
Al Viro3e335452007-08-23 00:45:46 -04002420 lp->init_block->rx_ring = cpu_to_le32(lp->rx_ring_dma_addr);
2421 lp->init_block->tx_ring = cpu_to_le32(lp->tx_ring_dma_addr);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002422 wmb(); /* Make sure all changes are visible */
2423 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424}
2425
2426/* the pcnet32 has been issued a stop or reset. Wait for the stop bit
2427 * then flush the pending transmit operations, re-initialize the ring,
2428 * and tell the chip to initialize.
2429 */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002430static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431{
Don Fry1e56a4b2007-03-06 10:55:00 -08002432 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002433 unsigned long ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002436 /* wait for stop */
2437 for (i = 0; i < 100; i++)
stephen hemminger1d70cb02011-09-16 11:06:26 +00002438 if (lp->a->read_csr(ioaddr, CSR0) & CSR0_STOP)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002439 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440
Joe Perches13ff83b2010-02-15 08:34:25 +00002441 if (i >= 100)
2442 netif_err(lp, drv, dev, "%s timed out waiting for stop\n",
2443 __func__);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002444
2445 pcnet32_purge_tx_ring(dev);
2446 if (pcnet32_init_ring(dev))
2447 return;
2448
2449 /* ReInit Ring */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002450 lp->a->write_csr(ioaddr, CSR0, CSR0_INIT);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002451 i = 0;
2452 while (i++ < 1000)
stephen hemminger1d70cb02011-09-16 11:06:26 +00002453 if (lp->a->read_csr(ioaddr, CSR0) & CSR0_IDON)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002454 break;
2455
stephen hemminger1d70cb02011-09-16 11:06:26 +00002456 lp->a->write_csr(ioaddr, CSR0, csr0_bits);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457}
2458
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002459static void pcnet32_tx_timeout(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460{
Don Fry1e56a4b2007-03-06 10:55:00 -08002461 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002462 unsigned long ioaddr = dev->base_addr, flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002464 spin_lock_irqsave(&lp->lock, flags);
2465 /* Transmitter timeout, serious problems. */
2466 if (pcnet32_debug & NETIF_MSG_DRV)
Joe Perches13ff83b2010-02-15 08:34:25 +00002467 pr_err("%s: transmit timed out, status %4.4x, resetting\n",
stephen hemminger1d70cb02011-09-16 11:06:26 +00002468 dev->name, lp->a->read_csr(ioaddr, CSR0));
2469 lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
Don Fry4f1e5ba2007-10-17 17:06:19 -07002470 dev->stats.tx_errors++;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002471 if (netif_msg_tx_err(lp)) {
2472 int i;
2473 printk(KERN_DEBUG
2474 " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
2475 lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
2476 lp->cur_rx);
2477 for (i = 0; i < lp->rx_ring_size; i++)
2478 printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
2479 le32_to_cpu(lp->rx_ring[i].base),
2480 (-le16_to_cpu(lp->rx_ring[i].buf_length)) &
2481 0xffff, le32_to_cpu(lp->rx_ring[i].msg_length),
2482 le16_to_cpu(lp->rx_ring[i].status));
2483 for (i = 0; i < lp->tx_ring_size; i++)
2484 printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
2485 le32_to_cpu(lp->tx_ring[i].base),
2486 (-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff,
2487 le32_to_cpu(lp->tx_ring[i].misc),
2488 le16_to_cpu(lp->tx_ring[i].status));
2489 printk("\n");
2490 }
Don Fryb368a3f2006-09-13 10:16:07 -07002491 pcnet32_restart(dev, CSR0_NORMAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492
Florian Westphal860e9532016-05-03 16:33:13 +02002493 netif_trans_update(dev); /* prevent tx timeout */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002494 netif_wake_queue(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002496 spin_unlock_irqrestore(&lp->lock, flags);
2497}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498
Stephen Hemminger613573252009-08-31 19:50:58 +00002499static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb,
2500 struct net_device *dev)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002501{
Don Fry1e56a4b2007-03-06 10:55:00 -08002502 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002503 unsigned long ioaddr = dev->base_addr;
2504 u16 status;
2505 int entry;
2506 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002508 spin_lock_irqsave(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509
Joe Perches13ff83b2010-02-15 08:34:25 +00002510 netif_printk(lp, tx_queued, KERN_DEBUG, dev,
2511 "%s() called, csr0 %4.4x\n",
stephen hemminger1d70cb02011-09-16 11:06:26 +00002512 __func__, lp->a->read_csr(ioaddr, CSR0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002514 /* Default status -- will not enable Successful-TxDone
2515 * interrupt when that option is available to us.
2516 */
2517 status = 0x8300;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002519 /* Fill in a Tx ring entry */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002521 /* Mask to ring buffer boundary. */
2522 entry = lp->cur_tx & lp->tx_mod_mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002524 /* Caution: the write order is important here, set the status
2525 * with the "ownership" bits last. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526
Al Viro3e335452007-08-23 00:45:46 -04002527 lp->tx_ring[entry].length = cpu_to_le16(-skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002529 lp->tx_ring[entry].misc = 0x00000000;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002531 lp->tx_dma_addr[entry] =
2532 pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE);
Don Fry4cc5c472014-02-17 20:57:59 -08002533 if (pci_dma_mapping_error(lp->pci_dev, lp->tx_dma_addr[entry])) {
Eric W. Biedermanaf9ba922014-03-15 15:49:08 -07002534 dev_kfree_skb_any(skb);
Don Fry4cc5c472014-02-17 20:57:59 -08002535 dev->stats.tx_dropped++;
2536 goto drop_packet;
2537 }
2538 lp->tx_skbuff[entry] = skb;
Al Viro3e335452007-08-23 00:45:46 -04002539 lp->tx_ring[entry].base = cpu_to_le32(lp->tx_dma_addr[entry]);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002540 wmb(); /* Make sure owner changes after all others are visible */
Al Viro3e335452007-08-23 00:45:46 -04002541 lp->tx_ring[entry].status = cpu_to_le16(status);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002542
2543 lp->cur_tx++;
Don Fry4f1e5ba2007-10-17 17:06:19 -07002544 dev->stats.tx_bytes += skb->len;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002545
2546 /* Trigger an immediate send poll. */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002547 lp->a->write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002548
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002549 if (lp->tx_ring[(entry + 1) & lp->tx_mod_mask].base != 0) {
2550 lp->tx_full = 1;
2551 netif_stop_queue(dev);
2552 }
Don Fry4cc5c472014-02-17 20:57:59 -08002553drop_packet:
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002554 spin_unlock_irqrestore(&lp->lock, flags);
Patrick McHardy6ed10652009-06-23 06:03:08 +00002555 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556}
2557
2558/* The PCNET32 interrupt handler. */
2559static irqreturn_t
David Howells7d12e782006-10-05 14:55:46 +01002560pcnet32_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002562 struct net_device *dev = dev_id;
2563 struct pcnet32_private *lp;
2564 unsigned long ioaddr;
Don Fry5c993462006-09-13 10:15:43 -07002565 u16 csr0;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002566 int boguscnt = max_interrupt_work;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002568 ioaddr = dev->base_addr;
Don Fry1e56a4b2007-03-06 10:55:00 -08002569 lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002570
2571 spin_lock(&lp->lock);
2572
stephen hemminger1d70cb02011-09-16 11:06:26 +00002573 csr0 = lp->a->read_csr(ioaddr, CSR0);
Don Fry3904c322006-09-13 10:16:38 -07002574 while ((csr0 & 0x8f00) && --boguscnt >= 0) {
Joe Perches9e3f8062010-02-15 08:34:26 +00002575 if (csr0 == 0xffff)
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002576 break; /* PCMCIA remove happened */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002577 /* Acknowledge all of the current interrupt sources ASAP. */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002578 lp->a->write_csr(ioaddr, CSR0, csr0 & ~0x004f);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002579
Joe Perches13ff83b2010-02-15 08:34:25 +00002580 netif_printk(lp, intr, KERN_DEBUG, dev,
2581 "interrupt csr0=%#2.2x new csr=%#2.2x\n",
stephen hemminger1d70cb02011-09-16 11:06:26 +00002582 csr0, lp->a->read_csr(ioaddr, CSR0));
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002583
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002584 /* Log misc errors. */
2585 if (csr0 & 0x4000)
Don Fry4f1e5ba2007-10-17 17:06:19 -07002586 dev->stats.tx_errors++; /* Tx babble. */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002587 if (csr0 & 0x1000) {
2588 /*
Don Fry3904c322006-09-13 10:16:38 -07002589 * This happens when our receive ring is full. This
2590 * shouldn't be a problem as we will see normal rx
2591 * interrupts for the frames in the receive ring. But
2592 * there are some PCI chipsets (I can reproduce this
2593 * on SP3G with Intel saturn chipset) which have
2594 * sometimes problems and will fill up the receive
2595 * ring with error descriptors. In this situation we
2596 * don't get a rx interrupt, but a missed frame
Don Fry7de745e2006-09-13 10:16:53 -07002597 * interrupt sooner or later.
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002598 */
Don Fry4f1e5ba2007-10-17 17:06:19 -07002599 dev->stats.rx_errors++; /* Missed a Rx frame. */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002600 }
2601 if (csr0 & 0x0800) {
Joe Perches13ff83b2010-02-15 08:34:25 +00002602 netif_err(lp, drv, dev, "Bus master arbitration failure, status %4.4x\n",
2603 csr0);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002604 /* unlike for the lance, there is no restart needed */
2605 }
Ben Hutchings288379f2009-01-19 16:43:59 -08002606 if (napi_schedule_prep(&lp->napi)) {
Don Fry7de745e2006-09-13 10:16:53 -07002607 u16 val;
2608 /* set interrupt masks */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002609 val = lp->a->read_csr(ioaddr, CSR3);
Don Fry7de745e2006-09-13 10:16:53 -07002610 val |= 0x5f00;
stephen hemminger1d70cb02011-09-16 11:06:26 +00002611 lp->a->write_csr(ioaddr, CSR3, val);
John Dykstrace105a02009-04-29 17:22:30 -07002612
Ben Hutchings288379f2009-01-19 16:43:59 -08002613 __napi_schedule(&lp->napi);
Don Fry7de745e2006-09-13 10:16:53 -07002614 break;
2615 }
stephen hemminger1d70cb02011-09-16 11:06:26 +00002616 csr0 = lp->a->read_csr(ioaddr, CSR0);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002617 }
2618
Joe Perches13ff83b2010-02-15 08:34:25 +00002619 netif_printk(lp, intr, KERN_DEBUG, dev,
2620 "exiting interrupt, csr0=%#4.4x\n",
stephen hemminger1d70cb02011-09-16 11:06:26 +00002621 lp->a->read_csr(ioaddr, CSR0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002623 spin_unlock(&lp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002625 return IRQ_HANDLED;
2626}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002628static int pcnet32_close(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002630 unsigned long ioaddr = dev->base_addr;
Don Fry1e56a4b2007-03-06 10:55:00 -08002631 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002632 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002634 del_timer_sync(&lp->watchdog_timer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002636 netif_stop_queue(dev);
Stephen Hemmingerbea33482007-10-03 16:41:36 -07002637 napi_disable(&lp->napi);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002639 spin_lock_irqsave(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640
stephen hemminger1d70cb02011-09-16 11:06:26 +00002641 dev->stats.rx_missed_errors = lp->a->read_csr(ioaddr, 112);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002642
Joe Perches13ff83b2010-02-15 08:34:25 +00002643 netif_printk(lp, ifdown, KERN_DEBUG, dev,
2644 "Shutting down ethercard, status was %2.2x\n",
stephen hemminger1d70cb02011-09-16 11:06:26 +00002645 lp->a->read_csr(ioaddr, CSR0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002647 /* We stop the PCNET32 here -- it occasionally polls memory if we don't. */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002648 lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 /*
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002651 * Switch back to 16bit mode to avoid problems with dumb
2652 * DOS packet driver after a warm reboot
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653 */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002654 lp->a->write_bcr(ioaddr, 20, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002656 spin_unlock_irqrestore(&lp->lock, flags);
2657
2658 free_irq(dev->irq, dev);
2659
2660 spin_lock_irqsave(&lp->lock, flags);
2661
Don Fryac5bfe42006-06-29 13:55:27 -07002662 pcnet32_purge_rx_ring(dev);
2663 pcnet32_purge_tx_ring(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002664
2665 spin_unlock_irqrestore(&lp->lock, flags);
2666
2667 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668}
2669
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002670static struct net_device_stats *pcnet32_get_stats(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671{
Don Fry1e56a4b2007-03-06 10:55:00 -08002672 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002673 unsigned long ioaddr = dev->base_addr;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002674 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002675
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002676 spin_lock_irqsave(&lp->lock, flags);
stephen hemminger1d70cb02011-09-16 11:06:26 +00002677 dev->stats.rx_missed_errors = lp->a->read_csr(ioaddr, 112);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002678 spin_unlock_irqrestore(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679
Don Fry4f1e5ba2007-10-17 17:06:19 -07002680 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681}
2682
2683/* taken from the sunlance driver, which it took from the depca driver */
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002684static void pcnet32_load_multicast(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685{
Don Fry1e56a4b2007-03-06 10:55:00 -08002686 struct pcnet32_private *lp = netdev_priv(dev);
Don Fry6ecb7662007-03-06 10:45:23 -08002687 volatile struct pcnet32_init_block *ib = lp->init_block;
Al Viro3e335452007-08-23 00:45:46 -04002688 volatile __le16 *mcast_table = (__le16 *)ib->filter;
Jiri Pirko22bedad32010-04-01 21:22:57 +00002689 struct netdev_hw_addr *ha;
Don Frydf27f4a2006-06-29 13:55:02 -07002690 unsigned long ioaddr = dev->base_addr;
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002691 int i;
2692 u32 crc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002693
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002694 /* set all multicast bits */
2695 if (dev->flags & IFF_ALLMULTI) {
Al Viro3e335452007-08-23 00:45:46 -04002696 ib->filter[0] = cpu_to_le32(~0U);
2697 ib->filter[1] = cpu_to_le32(~0U);
stephen hemminger1d70cb02011-09-16 11:06:26 +00002698 lp->a->write_csr(ioaddr, PCNET32_MC_FILTER, 0xffff);
2699 lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+1, 0xffff);
2700 lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+2, 0xffff);
2701 lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+3, 0xffff);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002702 return;
2703 }
2704 /* clear the multicast filter */
2705 ib->filter[0] = 0;
2706 ib->filter[1] = 0;
2707
2708 /* Add addresses */
Jiri Pirko22bedad32010-04-01 21:22:57 +00002709 netdev_for_each_mc_addr(ha, dev) {
Tobias Klauser498d8e22011-07-07 22:06:26 +00002710 crc = ether_crc_le(6, ha->addr);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002711 crc = crc >> 26;
Al Viro3e335452007-08-23 00:45:46 -04002712 mcast_table[crc >> 4] |= cpu_to_le16(1 << (crc & 0xf));
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002713 }
Don Frydf27f4a2006-06-29 13:55:02 -07002714 for (i = 0; i < 4; i++)
stephen hemminger1d70cb02011-09-16 11:06:26 +00002715 lp->a->write_csr(ioaddr, PCNET32_MC_FILTER + i,
Don Frydf27f4a2006-06-29 13:55:02 -07002716 le16_to_cpu(mcast_table[i]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717}
2718
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719/*
2720 * Set or clear the multicast filter for this adaptor.
2721 */
2722static void pcnet32_set_multicast_list(struct net_device *dev)
2723{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002724 unsigned long ioaddr = dev->base_addr, flags;
Don Fry1e56a4b2007-03-06 10:55:00 -08002725 struct pcnet32_private *lp = netdev_priv(dev);
Don Frydf27f4a2006-06-29 13:55:02 -07002726 int csr15, suspended;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002728 spin_lock_irqsave(&lp->lock, flags);
Don Frydf27f4a2006-06-29 13:55:02 -07002729 suspended = pcnet32_suspend(dev, &flags, 0);
stephen hemminger1d70cb02011-09-16 11:06:26 +00002730 csr15 = lp->a->read_csr(ioaddr, CSR15);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002731 if (dev->flags & IFF_PROMISC) {
2732 /* Log any net taps. */
Joe Perches13ff83b2010-02-15 08:34:25 +00002733 netif_info(lp, hw, dev, "Promiscuous mode enabled\n");
Don Fry6ecb7662007-03-06 10:45:23 -08002734 lp->init_block->mode =
Al Viro3e335452007-08-23 00:45:46 -04002735 cpu_to_le16(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) <<
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002736 7);
stephen hemminger1d70cb02011-09-16 11:06:26 +00002737 lp->a->write_csr(ioaddr, CSR15, csr15 | 0x8000);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002738 } else {
Don Fry6ecb7662007-03-06 10:45:23 -08002739 lp->init_block->mode =
Al Viro3e335452007-08-23 00:45:46 -04002740 cpu_to_le16((lp->options & PCNET32_PORT_PORTSEL) << 7);
stephen hemminger1d70cb02011-09-16 11:06:26 +00002741 lp->a->write_csr(ioaddr, CSR15, csr15 & 0x7fff);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002742 pcnet32_load_multicast(dev);
2743 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744
Don Frydf27f4a2006-06-29 13:55:02 -07002745 if (suspended) {
Ondrej Zarycce5fba2017-02-13 23:45:46 +01002746 pcnet32_clr_suspend(lp, ioaddr);
Don Fryb368a3f2006-09-13 10:16:07 -07002747 } else {
stephen hemminger1d70cb02011-09-16 11:06:26 +00002748 lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
Don Frydf27f4a2006-06-29 13:55:02 -07002749 pcnet32_restart(dev, CSR0_NORMAL);
2750 netif_wake_queue(dev);
2751 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002753 spin_unlock_irqrestore(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754}
2755
2756/* This routine assumes that the lp->lock is held */
2757static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
2758{
Don Fry1e56a4b2007-03-06 10:55:00 -08002759 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002760 unsigned long ioaddr = dev->base_addr;
2761 u16 val_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002763 if (!lp->mii)
2764 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765
stephen hemminger1d70cb02011-09-16 11:06:26 +00002766 lp->a->write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
2767 val_out = lp->a->read_bcr(ioaddr, 34);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002769 return val_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770}
2771
2772/* This routine assumes that the lp->lock is held */
2773static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
2774{
Don Fry1e56a4b2007-03-06 10:55:00 -08002775 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002776 unsigned long ioaddr = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002778 if (!lp->mii)
2779 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780
stephen hemminger1d70cb02011-09-16 11:06:26 +00002781 lp->a->write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
2782 lp->a->write_bcr(ioaddr, 34, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783}
2784
2785static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2786{
Don Fry1e56a4b2007-03-06 10:55:00 -08002787 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002788 int rc;
2789 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002790
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002791 /* SIOC[GS]MIIxxx ioctls */
2792 if (lp->mii) {
2793 spin_lock_irqsave(&lp->lock, flags);
2794 rc = generic_mii_ioctl(&lp->mii_if, if_mii(rq), cmd, NULL);
2795 spin_unlock_irqrestore(&lp->lock, flags);
2796 } else {
2797 rc = -EOPNOTSUPP;
2798 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002800 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801}
2802
Don Fryac62ef02006-03-20 15:26:03 -08002803static int pcnet32_check_otherphy(struct net_device *dev)
2804{
Don Fry1e56a4b2007-03-06 10:55:00 -08002805 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002806 struct mii_if_info mii = lp->mii_if;
2807 u16 bmcr;
2808 int i;
Don Fryac62ef02006-03-20 15:26:03 -08002809
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002810 for (i = 0; i < PCNET32_MAX_PHYS; i++) {
2811 if (i == lp->mii_if.phy_id)
2812 continue; /* skip active phy */
2813 if (lp->phymask & (1 << i)) {
2814 mii.phy_id = i;
2815 if (mii_link_ok(&mii)) {
2816 /* found PHY with active link */
Joe Perches13ff83b2010-02-15 08:34:25 +00002817 netif_info(lp, link, dev, "Using PHY number %d\n",
2818 i);
Don Fryac62ef02006-03-20 15:26:03 -08002819
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002820 /* isolate inactive phy */
2821 bmcr =
2822 mdio_read(dev, lp->mii_if.phy_id, MII_BMCR);
2823 mdio_write(dev, lp->mii_if.phy_id, MII_BMCR,
2824 bmcr | BMCR_ISOLATE);
Don Fryac62ef02006-03-20 15:26:03 -08002825
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002826 /* de-isolate new phy */
2827 bmcr = mdio_read(dev, i, MII_BMCR);
2828 mdio_write(dev, i, MII_BMCR,
2829 bmcr & ~BMCR_ISOLATE);
Don Fryac62ef02006-03-20 15:26:03 -08002830
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002831 /* set new phy address */
2832 lp->mii_if.phy_id = i;
2833 return 1;
2834 }
2835 }
Don Fryac62ef02006-03-20 15:26:03 -08002836 }
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002837 return 0;
Don Fryac62ef02006-03-20 15:26:03 -08002838}
2839
2840/*
2841 * Show the status of the media. Similar to mii_check_media however it
2842 * correctly shows the link speed for all (tested) pcnet32 variants.
2843 * Devices with no mii just report link state without speed.
2844 *
2845 * Caller is assumed to hold and release the lp->lock.
2846 */
2847
2848static void pcnet32_check_media(struct net_device *dev, int verbose)
2849{
Don Fry1e56a4b2007-03-06 10:55:00 -08002850 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002851 int curr_link;
2852 int prev_link = netif_carrier_ok(dev) ? 1 : 0;
2853 u32 bcr9;
Don Fryac62ef02006-03-20 15:26:03 -08002854
Don Fryac62ef02006-03-20 15:26:03 -08002855 if (lp->mii) {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002856 curr_link = mii_link_ok(&lp->mii_if);
Ondrej Zary2be4cb92017-02-13 23:45:47 +01002857 } else if (lp->chip_version == PCNET32_79C970A) {
2858 ulong ioaddr = dev->base_addr; /* card base I/O address */
2859 /* only read link if port is set to TP */
2860 if (!lp->autoneg && lp->port_tp)
2861 curr_link = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
2862 else /* link always up for AUI port or port auto select */
2863 curr_link = 1;
Don Fryac62ef02006-03-20 15:26:03 -08002864 } else {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002865 ulong ioaddr = dev->base_addr; /* card base I/O address */
stephen hemminger1d70cb02011-09-16 11:06:26 +00002866 curr_link = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
Don Fryac62ef02006-03-20 15:26:03 -08002867 }
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002868 if (!curr_link) {
2869 if (prev_link || verbose) {
2870 netif_carrier_off(dev);
Joe Perches13ff83b2010-02-15 08:34:25 +00002871 netif_info(lp, link, dev, "link down\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002872 }
2873 if (lp->phycount > 1) {
2874 curr_link = pcnet32_check_otherphy(dev);
2875 prev_link = 0;
2876 }
2877 } else if (verbose || !prev_link) {
2878 netif_carrier_on(dev);
2879 if (lp->mii) {
2880 if (netif_msg_link(lp)) {
David Decotigny8ae6daca2011-04-27 18:32:38 +00002881 struct ethtool_cmd ecmd = {
2882 .cmd = ETHTOOL_GSET };
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002883 mii_ethtool_gset(&lp->mii_if, &ecmd);
David Decotigny8ae6daca2011-04-27 18:32:38 +00002884 netdev_info(dev, "link up, %uMbps, %s-duplex\n",
2885 ethtool_cmd_speed(&ecmd),
Joe Perches13ff83b2010-02-15 08:34:25 +00002886 (ecmd.duplex == DUPLEX_FULL)
2887 ? "full" : "half");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002888 }
stephen hemminger1d70cb02011-09-16 11:06:26 +00002889 bcr9 = lp->a->read_bcr(dev->base_addr, 9);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002890 if ((bcr9 & (1 << 0)) != lp->mii_if.full_duplex) {
2891 if (lp->mii_if.full_duplex)
2892 bcr9 |= (1 << 0);
2893 else
2894 bcr9 &= ~(1 << 0);
stephen hemminger1d70cb02011-09-16 11:06:26 +00002895 lp->a->write_bcr(dev->base_addr, 9, bcr9);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002896 }
2897 } else {
Joe Perches13ff83b2010-02-15 08:34:25 +00002898 netif_info(lp, link, dev, "link up\n");
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002899 }
2900 }
Don Fryac62ef02006-03-20 15:26:03 -08002901}
2902
2903/*
2904 * Check for loss of link and link establishment.
Ben Hutchings5bdc7382015-01-16 17:55:35 +00002905 * Could possibly be changed to use mii_check_media instead.
Don Fryac62ef02006-03-20 15:26:03 -08002906 */
2907
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908static void pcnet32_watchdog(struct net_device *dev)
2909{
Don Fry1e56a4b2007-03-06 10:55:00 -08002910 struct pcnet32_private *lp = netdev_priv(dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002911 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002913 /* Print the link status if it has changed */
2914 spin_lock_irqsave(&lp->lock, flags);
2915 pcnet32_check_media(dev, 0);
2916 spin_unlock_irqrestore(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917
Stephen Hemminger283a21d32009-01-08 11:17:13 -08002918 mod_timer(&lp->watchdog_timer, round_jiffies(PCNET32_WATCHDOG_TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919}
2920
Don Fry917270c2007-08-26 21:22:32 -07002921static int pcnet32_pm_suspend(struct pci_dev *pdev, pm_message_t state)
2922{
2923 struct net_device *dev = pci_get_drvdata(pdev);
2924
2925 if (netif_running(dev)) {
2926 netif_device_detach(dev);
2927 pcnet32_close(dev);
2928 }
2929 pci_save_state(pdev);
2930 pci_set_power_state(pdev, pci_choose_state(pdev, state));
2931 return 0;
2932}
2933
2934static int pcnet32_pm_resume(struct pci_dev *pdev)
2935{
2936 struct net_device *dev = pci_get_drvdata(pdev);
2937
2938 pci_set_power_state(pdev, PCI_D0);
2939 pci_restore_state(pdev);
2940
2941 if (netif_running(dev)) {
2942 pcnet32_open(dev);
2943 netif_device_attach(dev);
2944 }
2945 return 0;
2946}
2947
Bill Pembertona9590872012-12-03 09:22:56 -05002948static void pcnet32_remove_one(struct pci_dev *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002950 struct net_device *dev = pci_get_drvdata(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002952 if (dev) {
Don Fry1e56a4b2007-03-06 10:55:00 -08002953 struct pcnet32_private *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002955 unregister_netdev(dev);
2956 pcnet32_free_ring(dev);
2957 release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
Jeff Garzik7d2e3cb2008-05-13 01:41:58 -04002958 pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
Don Fry6ecb7662007-03-06 10:45:23 -08002959 lp->init_block, lp->init_dma_addr);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002960 free_netdev(dev);
2961 pci_disable_device(pdev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002962 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963}
2964
2965static struct pci_driver pcnet32_driver = {
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002966 .name = DRV_NAME,
2967 .probe = pcnet32_probe_pci,
Bill Pembertona9590872012-12-03 09:22:56 -05002968 .remove = pcnet32_remove_one,
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002969 .id_table = pcnet32_pci_tbl,
Don Fry917270c2007-08-26 21:22:32 -07002970 .suspend = pcnet32_pm_suspend,
2971 .resume = pcnet32_pm_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972};
2973
2974/* An additional parameter that may be passed in... */
2975static int debug = -1;
2976static int tx_start_pt = -1;
2977static int pcnet32_have_pci;
2978
2979module_param(debug, int, 0);
2980MODULE_PARM_DESC(debug, DRV_NAME " debug level");
2981module_param(max_interrupt_work, int, 0);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002982MODULE_PARM_DESC(max_interrupt_work,
2983 DRV_NAME " maximum events handled per interrupt");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984module_param(rx_copybreak, int, 0);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002985MODULE_PARM_DESC(rx_copybreak,
2986 DRV_NAME " copy breakpoint for copy-only-tiny-frames");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987module_param(tx_start_pt, int, 0);
2988MODULE_PARM_DESC(tx_start_pt, DRV_NAME " transmit start point (0-3)");
2989module_param(pcnet32vlb, int, 0);
2990MODULE_PARM_DESC(pcnet32vlb, DRV_NAME " Vesa local bus (VLB) support (0/1)");
2991module_param_array(options, int, NULL, 0);
2992MODULE_PARM_DESC(options, DRV_NAME " initial option setting(s) (0-15)");
2993module_param_array(full_duplex, int, NULL, 0);
2994MODULE_PARM_DESC(full_duplex, DRV_NAME " full duplex setting(s) (1)");
2995/* Module Parameter for HomePNA cards added by Patrick Simmons, 2004 */
2996module_param_array(homepna, int, NULL, 0);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05002997MODULE_PARM_DESC(homepna,
2998 DRV_NAME
2999 " mode for 79C978 cards (1 for HomePNA, 0 for Ethernet, default Ethernet");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000
3001MODULE_AUTHOR("Thomas Bogendoerfer");
3002MODULE_DESCRIPTION("Driver for PCnet32 and PCnetPCI based ethercards");
3003MODULE_LICENSE("GPL");
3004
3005#define PCNET32_MSG_DEFAULT (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
3006
3007static int __init pcnet32_init_module(void)
3008{
Joe Perches13ff83b2010-02-15 08:34:25 +00003009 pr_info("%s", version);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003011 pcnet32_debug = netif_msg_init(debug, PCNET32_MSG_DEFAULT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003013 if ((tx_start_pt >= 0) && (tx_start_pt <= 3))
3014 tx_start = tx_start_pt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003016 /* find the PCI devices */
Jeff Garzik29917622006-08-19 17:48:59 -04003017 if (!pci_register_driver(&pcnet32_driver))
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003018 pcnet32_have_pci = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003019
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003020 /* should we find any remaining VLbus devices ? */
3021 if (pcnet32vlb)
Don Frydcaf9762006-06-29 13:52:29 -07003022 pcnet32_probe_vlbus(pcnet32_portlist);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003024 if (cards_found && (pcnet32_debug & NETIF_MSG_PROBE))
Joe Perches13ff83b2010-02-15 08:34:25 +00003025 pr_info("%d cards_found\n", cards_found);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003027 return (pcnet32_have_pci + cards_found) ? 0 : -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028}
3029
3030static void __exit pcnet32_cleanup_module(void)
3031{
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003032 struct net_device *next_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003034 while (pcnet32_dev) {
Don Fry1e56a4b2007-03-06 10:55:00 -08003035 struct pcnet32_private *lp = netdev_priv(pcnet32_dev);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003036 next_dev = lp->next;
3037 unregister_netdev(pcnet32_dev);
3038 pcnet32_free_ring(pcnet32_dev);
3039 release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
Jeff Garzik7d2e3cb2008-05-13 01:41:58 -04003040 pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
Don Fry6ecb7662007-03-06 10:45:23 -08003041 lp->init_block, lp->init_dma_addr);
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003042 free_netdev(pcnet32_dev);
3043 pcnet32_dev = next_dev;
3044 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003045
Jeff Garzik4a5e8e22006-03-21 16:15:44 -05003046 if (pcnet32_have_pci)
3047 pci_unregister_driver(&pcnet32_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003048}
3049
3050module_init(pcnet32_init_module);
3051module_exit(pcnet32_cleanup_module);
3052
3053/*
3054 * Local variables:
3055 * c-indent-level: 4
3056 * tab-width: 8
3057 * End:
3058 */