blob: d0dbbf39349a3cb87d6eb19c51591bb736c9b9f5 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* 8139cp.c: A Linux PCI Ethernet driver for the RealTek 8139C+ chips. */
2/*
3 Copyright 2001-2004 Jeff Garzik <jgarzik@pobox.com>
4
5 Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com) [tg3.c]
6 Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com) [sungem.c]
7 Copyright 2001 Manfred Spraul [natsemi.c]
8 Copyright 1999-2001 by Donald Becker. [natsemi.c]
9 Written 1997-2001 by Donald Becker. [8139too.c]
10 Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>. [acenic.c]
11
12 This software may be used and distributed according to the terms of
13 the GNU General Public License (GPL), incorporated herein by reference.
14 Drivers based on or derived from this code fall under the GPL and must
15 retain the authorship, copyright and license notice. This file is not
16 a complete program and may only be used when the entire operating
17 system is licensed under the GPL.
18
19 See the file COPYING in this distribution for more information.
20
21 Contributors:
Jeff Garzikf3b197a2006-05-26 21:39:03 -040022
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 Wake-on-LAN support - Felipe Damasio <felipewd@terra.com.br>
24 PCI suspend/resume - Felipe Damasio <felipewd@terra.com.br>
25 LinkChg interrupt - Felipe Damasio <felipewd@terra.com.br>
Jeff Garzikf3b197a2006-05-26 21:39:03 -040026
Linus Torvalds1da177e2005-04-16 15:20:36 -070027 TODO:
28 * Test Tx checksumming thoroughly
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30 Low priority TODO:
31 * Complete reset on PciErr
32 * Consider Rx interrupt mitigation using TimerIntr
33 * Investigate using skb->priority with h/w VLAN priority
34 * Investigate using High Priority Tx Queue with skb->priority
35 * Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
36 * Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error
37 * Implement Tx software interrupt mitigation via
38 Tx descriptor bit
39 * The real minimum of CP_MIN_MTU is 4 bytes. However,
40 for this to be supported, one must(?) turn on packet padding.
41 * Support external MII transceivers (patch available)
42
43 NOTES:
44 * TX checksumming is considered experimental. It is off by
45 default, use ethtool to turn it on.
46
47 */
48
49#define DRV_NAME "8139cp"
Andy Gospodarekd5b20692006-09-11 17:39:18 -040050#define DRV_VERSION "1.3"
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#define DRV_RELDATE "Mar 22, 2004"
52
53
Linus Torvalds1da177e2005-04-16 15:20:36 -070054#include <linux/module.h>
Stephen Hemmingere21ba282005-05-12 19:33:26 -040055#include <linux/moduleparam.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070056#include <linux/kernel.h>
57#include <linux/compiler.h>
58#include <linux/netdevice.h>
59#include <linux/etherdevice.h>
60#include <linux/init.h>
61#include <linux/pci.h>
Tobias Klauser8662d062005-05-12 22:19:39 -040062#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070063#include <linux/delay.h>
64#include <linux/ethtool.h>
65#include <linux/mii.h>
66#include <linux/if_vlan.h>
67#include <linux/crc32.h>
68#include <linux/in.h>
69#include <linux/ip.h>
70#include <linux/tcp.h>
71#include <linux/udp.h>
72#include <linux/cache.h>
73#include <asm/io.h>
74#include <asm/irq.h>
75#include <asm/uaccess.h>
76
77/* VLAN tagging feature enable/disable */
78#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
79#define CP_VLAN_TAG_USED 1
80#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \
Al Virocf983012007-08-22 21:18:56 -040081 do { (tx_desc)->opts2 = cpu_to_le32(vlan_tag_value); } while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -070082#else
83#define CP_VLAN_TAG_USED 0
84#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \
85 do { (tx_desc)->opts2 = 0; } while (0)
86#endif
87
88/* These identify the driver base version and may not be removed. */
89static char version[] =
90KERN_INFO DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
91
92MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
93MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver");
a78d8922005-05-12 19:35:42 -040094MODULE_VERSION(DRV_VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095MODULE_LICENSE("GPL");
96
97static int debug = -1;
Stephen Hemmingere21ba282005-05-12 19:33:26 -040098module_param(debug, int, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number");
100
101/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
102 The RTL chips use a 64 element hash table based on the Ethernet CRC. */
103static int multicast_filter_limit = 32;
Stephen Hemmingere21ba282005-05-12 19:33:26 -0400104module_param(multicast_filter_limit, int, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses");
106
107#define PFX DRV_NAME ": "
108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109#define CP_DEF_MSG_ENABLE (NETIF_MSG_DRV | \
110 NETIF_MSG_PROBE | \
111 NETIF_MSG_LINK)
112#define CP_NUM_STATS 14 /* struct cp_dma_stats, plus one */
113#define CP_STATS_SIZE 64 /* size in bytes of DMA stats block */
114#define CP_REGS_SIZE (0xff + 1)
115#define CP_REGS_VER 1 /* version 1 */
116#define CP_RX_RING_SIZE 64
117#define CP_TX_RING_SIZE 64
118#define CP_RING_BYTES \
119 ((sizeof(struct cp_desc) * CP_RX_RING_SIZE) + \
120 (sizeof(struct cp_desc) * CP_TX_RING_SIZE) + \
121 CP_STATS_SIZE)
122#define NEXT_TX(N) (((N) + 1) & (CP_TX_RING_SIZE - 1))
123#define NEXT_RX(N) (((N) + 1) & (CP_RX_RING_SIZE - 1))
124#define TX_BUFFS_AVAIL(CP) \
125 (((CP)->tx_tail <= (CP)->tx_head) ? \
126 (CP)->tx_tail + (CP_TX_RING_SIZE - 1) - (CP)->tx_head : \
127 (CP)->tx_tail - (CP)->tx_head - 1)
128
129#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130#define CP_INTERNAL_PHY 32
131
132/* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024, 7==end of packet. */
133#define RX_FIFO_THRESH 5 /* Rx buffer level before first PCI xfer. */
134#define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 */
135#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
136#define TX_EARLY_THRESH 256 /* Early Tx threshold, in bytes */
137
138/* Time in jiffies before concluding the transmitter is hung. */
139#define TX_TIMEOUT (6*HZ)
140
141/* hardware minimum and maximum for a single frame's data payload */
142#define CP_MIN_MTU 60 /* TODO: allow lower, but pad */
143#define CP_MAX_MTU 4096
144
145enum {
146 /* NIC register offsets */
147 MAC0 = 0x00, /* Ethernet hardware address. */
148 MAR0 = 0x08, /* Multicast filter. */
149 StatsAddr = 0x10, /* 64-bit start addr of 64-byte DMA stats blk */
150 TxRingAddr = 0x20, /* 64-bit start addr of Tx ring */
151 HiTxRingAddr = 0x28, /* 64-bit start addr of high priority Tx ring */
152 Cmd = 0x37, /* Command register */
153 IntrMask = 0x3C, /* Interrupt mask */
154 IntrStatus = 0x3E, /* Interrupt status */
155 TxConfig = 0x40, /* Tx configuration */
156 ChipVersion = 0x43, /* 8-bit chip version, inside TxConfig */
157 RxConfig = 0x44, /* Rx configuration */
158 RxMissed = 0x4C, /* 24 bits valid, write clears */
159 Cfg9346 = 0x50, /* EEPROM select/control; Cfg reg [un]lock */
160 Config1 = 0x52, /* Config1 */
161 Config3 = 0x59, /* Config3 */
162 Config4 = 0x5A, /* Config4 */
163 MultiIntr = 0x5C, /* Multiple interrupt select */
164 BasicModeCtrl = 0x62, /* MII BMCR */
165 BasicModeStatus = 0x64, /* MII BMSR */
166 NWayAdvert = 0x66, /* MII ADVERTISE */
167 NWayLPAR = 0x68, /* MII LPA */
168 NWayExpansion = 0x6A, /* MII Expansion */
169 Config5 = 0xD8, /* Config5 */
170 TxPoll = 0xD9, /* Tell chip to check Tx descriptors for work */
171 RxMaxSize = 0xDA, /* Max size of an Rx packet (8169 only) */
172 CpCmd = 0xE0, /* C+ Command register (C+ mode only) */
173 IntrMitigate = 0xE2, /* rx/tx interrupt mitigation control */
174 RxRingAddr = 0xE4, /* 64-bit start addr of Rx ring */
175 TxThresh = 0xEC, /* Early Tx threshold */
176 OldRxBufAddr = 0x30, /* DMA address of Rx ring buffer (C mode) */
177 OldTSD0 = 0x10, /* DMA address of first Tx desc (C mode) */
178
179 /* Tx and Rx status descriptors */
180 DescOwn = (1 << 31), /* Descriptor is owned by NIC */
181 RingEnd = (1 << 30), /* End of descriptor ring */
182 FirstFrag = (1 << 29), /* First segment of a packet */
183 LastFrag = (1 << 28), /* Final segment of a packet */
Jeff Garzikfcec3452005-05-12 19:28:49 -0400184 LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */
185 MSSShift = 16, /* MSS value position */
186 MSSMask = 0xfff, /* MSS value: 11 bits */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 TxError = (1 << 23), /* Tx error summary */
188 RxError = (1 << 20), /* Rx error summary */
189 IPCS = (1 << 18), /* Calculate IP checksum */
190 UDPCS = (1 << 17), /* Calculate UDP/IP checksum */
191 TCPCS = (1 << 16), /* Calculate TCP/IP checksum */
192 TxVlanTag = (1 << 17), /* Add VLAN tag */
193 RxVlanTagged = (1 << 16), /* Rx VLAN tag available */
194 IPFail = (1 << 15), /* IP checksum failed */
195 UDPFail = (1 << 14), /* UDP/IP checksum failed */
196 TCPFail = (1 << 13), /* TCP/IP checksum failed */
197 NormalTxPoll = (1 << 6), /* One or more normal Tx packets to send */
198 PID1 = (1 << 17), /* 2 protocol id bits: 0==non-IP, */
199 PID0 = (1 << 16), /* 1==UDP/IP, 2==TCP/IP, 3==IP */
200 RxProtoTCP = 1,
201 RxProtoUDP = 2,
202 RxProtoIP = 3,
203 TxFIFOUnder = (1 << 25), /* Tx FIFO underrun */
204 TxOWC = (1 << 22), /* Tx Out-of-window collision */
205 TxLinkFail = (1 << 21), /* Link failed during Tx of packet */
206 TxMaxCol = (1 << 20), /* Tx aborted due to excessive collisions */
207 TxColCntShift = 16, /* Shift, to get 4-bit Tx collision cnt */
208 TxColCntMask = 0x01 | 0x02 | 0x04 | 0x08, /* 4-bit collision count */
209 RxErrFrame = (1 << 27), /* Rx frame alignment error */
210 RxMcast = (1 << 26), /* Rx multicast packet rcv'd */
211 RxErrCRC = (1 << 18), /* Rx CRC error */
212 RxErrRunt = (1 << 19), /* Rx error, packet < 64 bytes */
213 RxErrLong = (1 << 21), /* Rx error, packet > 4096 bytes */
214 RxErrFIFO = (1 << 22), /* Rx error, FIFO overflowed, pkt bad */
215
216 /* StatsAddr register */
217 DumpStats = (1 << 3), /* Begin stats dump */
218
219 /* RxConfig register */
220 RxCfgFIFOShift = 13, /* Shift, to get Rx FIFO thresh value */
221 RxCfgDMAShift = 8, /* Shift, to get Rx Max DMA value */
222 AcceptErr = 0x20, /* Accept packets with CRC errors */
223 AcceptRunt = 0x10, /* Accept runt (<64 bytes) packets */
224 AcceptBroadcast = 0x08, /* Accept broadcast packets */
225 AcceptMulticast = 0x04, /* Accept multicast packets */
226 AcceptMyPhys = 0x02, /* Accept pkts with our MAC as dest */
227 AcceptAllPhys = 0x01, /* Accept all pkts w/ physical dest */
228
229 /* IntrMask / IntrStatus registers */
230 PciErr = (1 << 15), /* System error on the PCI bus */
231 TimerIntr = (1 << 14), /* Asserted when TCTR reaches TimerInt value */
232 LenChg = (1 << 13), /* Cable length change */
233 SWInt = (1 << 8), /* Software-requested interrupt */
234 TxEmpty = (1 << 7), /* No Tx descriptors available */
235 RxFIFOOvr = (1 << 6), /* Rx FIFO Overflow */
236 LinkChg = (1 << 5), /* Packet underrun, or link change */
237 RxEmpty = (1 << 4), /* No Rx descriptors available */
238 TxErr = (1 << 3), /* Tx error */
239 TxOK = (1 << 2), /* Tx packet sent */
240 RxErr = (1 << 1), /* Rx error */
241 RxOK = (1 << 0), /* Rx packet received */
242 IntrResvd = (1 << 10), /* reserved, according to RealTek engineers,
243 but hardware likes to raise it */
244
245 IntrAll = PciErr | TimerIntr | LenChg | SWInt | TxEmpty |
246 RxFIFOOvr | LinkChg | RxEmpty | TxErr | TxOK |
247 RxErr | RxOK | IntrResvd,
248
249 /* C mode command register */
250 CmdReset = (1 << 4), /* Enable to reset; self-clearing */
251 RxOn = (1 << 3), /* Rx mode enable */
252 TxOn = (1 << 2), /* Tx mode enable */
253
254 /* C+ mode command register */
255 RxVlanOn = (1 << 6), /* Rx VLAN de-tagging enable */
256 RxChkSum = (1 << 5), /* Rx checksum offload enable */
257 PCIDAC = (1 << 4), /* PCI Dual Address Cycle (64-bit PCI) */
258 PCIMulRW = (1 << 3), /* Enable PCI read/write multiple */
259 CpRxOn = (1 << 1), /* Rx mode enable */
260 CpTxOn = (1 << 0), /* Tx mode enable */
261
262 /* Cfg9436 EEPROM control register */
263 Cfg9346_Lock = 0x00, /* Lock ConfigX/MII register access */
264 Cfg9346_Unlock = 0xC0, /* Unlock ConfigX/MII register access */
265
266 /* TxConfig register */
267 IFG = (1 << 25) | (1 << 24), /* standard IEEE interframe gap */
268 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
269
270 /* Early Tx Threshold register */
271 TxThreshMask = 0x3f, /* Mask bits 5-0 */
272 TxThreshMax = 2048, /* Max early Tx threshold */
273
274 /* Config1 register */
275 DriverLoaded = (1 << 5), /* Software marker, driver is loaded */
276 LWACT = (1 << 4), /* LWAKE active mode */
277 PMEnable = (1 << 0), /* Enable various PM features of chip */
278
279 /* Config3 register */
280 PARMEnable = (1 << 6), /* Enable auto-loading of PHY parms */
281 MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
282 LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
283
284 /* Config4 register */
285 LWPTN = (1 << 1), /* LWAKE Pattern */
286 LWPME = (1 << 4), /* LANWAKE vs PMEB */
287
288 /* Config5 register */
289 BWF = (1 << 6), /* Accept Broadcast wakeup frame */
290 MWF = (1 << 5), /* Accept Multicast wakeup frame */
291 UWF = (1 << 4), /* Accept Unicast wakeup frame */
292 LANWake = (1 << 1), /* Enable LANWake signal */
293 PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */
294
295 cp_norx_intr_mask = PciErr | LinkChg | TxOK | TxErr | TxEmpty,
296 cp_rx_intr_mask = RxOK | RxErr | RxEmpty | RxFIFOOvr,
297 cp_intr_mask = cp_rx_intr_mask | cp_norx_intr_mask,
298};
299
300static const unsigned int cp_rx_config =
301 (RX_FIFO_THRESH << RxCfgFIFOShift) |
302 (RX_DMA_BURST << RxCfgDMAShift);
303
304struct cp_desc {
Al Viro03233b92007-08-23 02:31:17 +0100305 __le32 opts1;
Al Virocf983012007-08-22 21:18:56 -0400306 __le32 opts2;
Al Viro03233b92007-08-23 02:31:17 +0100307 __le64 addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308};
309
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310struct cp_dma_stats {
Al Viro03233b92007-08-23 02:31:17 +0100311 __le64 tx_ok;
312 __le64 rx_ok;
313 __le64 tx_err;
314 __le32 rx_err;
315 __le16 rx_fifo;
316 __le16 frame_align;
317 __le32 tx_ok_1col;
318 __le32 tx_ok_mcol;
319 __le64 rx_ok_phys;
320 __le64 rx_ok_bcast;
321 __le32 rx_ok_mcast;
322 __le16 tx_abort;
323 __le16 tx_underrun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324} __attribute__((packed));
325
326struct cp_extra_stats {
327 unsigned long rx_frags;
328};
329
330struct cp_private {
331 void __iomem *regs;
332 struct net_device *dev;
333 spinlock_t lock;
334 u32 msg_enable;
335
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700336 struct napi_struct napi;
337
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 struct pci_dev *pdev;
339 u32 rx_config;
340 u16 cpcmd;
341
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 struct cp_extra_stats cp_stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343
Francois Romieud03d3762006-01-29 01:31:36 +0100344 unsigned rx_head ____cacheline_aligned;
345 unsigned rx_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 struct cp_desc *rx_ring;
Francois Romieu0ba894d2006-08-14 19:55:07 +0200347 struct sk_buff *rx_skb[CP_RX_RING_SIZE];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348
349 unsigned tx_head ____cacheline_aligned;
350 unsigned tx_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 struct cp_desc *tx_ring;
Francois Romieu48907e32006-09-10 23:33:44 +0200352 struct sk_buff *tx_skb[CP_TX_RING_SIZE];
Francois Romieud03d3762006-01-29 01:31:36 +0100353
354 unsigned rx_buf_sz;
355 unsigned wol_enabled : 1; /* Is Wake-on-LAN enabled? */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
357#if CP_VLAN_TAG_USED
358 struct vlan_group *vlgrp;
359#endif
Francois Romieud03d3762006-01-29 01:31:36 +0100360 dma_addr_t ring_dma;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361
362 struct mii_if_info mii_if;
363};
364
365#define cpr8(reg) readb(cp->regs + (reg))
366#define cpr16(reg) readw(cp->regs + (reg))
367#define cpr32(reg) readl(cp->regs + (reg))
368#define cpw8(reg,val) writeb((val), cp->regs + (reg))
369#define cpw16(reg,val) writew((val), cp->regs + (reg))
370#define cpw32(reg,val) writel((val), cp->regs + (reg))
371#define cpw8_f(reg,val) do { \
372 writeb((val), cp->regs + (reg)); \
373 readb(cp->regs + (reg)); \
374 } while (0)
375#define cpw16_f(reg,val) do { \
376 writew((val), cp->regs + (reg)); \
377 readw(cp->regs + (reg)); \
378 } while (0)
379#define cpw32_f(reg,val) do { \
380 writel((val), cp->regs + (reg)); \
381 readl(cp->regs + (reg)); \
382 } while (0)
383
384
385static void __cp_set_rx_mode (struct net_device *dev);
386static void cp_tx (struct cp_private *cp);
387static void cp_clean_rings (struct cp_private *cp);
Steffen Klassert7502cd12005-05-12 19:34:31 -0400388#ifdef CONFIG_NET_POLL_CONTROLLER
389static void cp_poll_controller(struct net_device *dev);
390#endif
Philip Craig722fdb32006-06-21 11:33:27 +1000391static int cp_get_eeprom_len(struct net_device *dev);
392static int cp_get_eeprom(struct net_device *dev,
393 struct ethtool_eeprom *eeprom, u8 *data);
394static int cp_set_eeprom(struct net_device *dev,
395 struct ethtool_eeprom *eeprom, u8 *data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396
397static struct pci_device_id cp_pci_tbl[] = {
Francois Romieucccb20d2006-08-16 13:07:18 +0200398 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139), },
399 { PCI_DEVICE(PCI_VENDOR_ID_TTTECH, PCI_DEVICE_ID_TTTECH_MC322), },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 { },
401};
402MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
403
404static struct {
405 const char str[ETH_GSTRING_LEN];
406} ethtool_stats_keys[] = {
407 { "tx_ok" },
408 { "rx_ok" },
409 { "tx_err" },
410 { "rx_err" },
411 { "rx_fifo" },
412 { "frame_align" },
413 { "tx_ok_1col" },
414 { "tx_ok_mcol" },
415 { "rx_ok_phys" },
416 { "rx_ok_bcast" },
417 { "rx_ok_mcast" },
418 { "tx_abort" },
419 { "tx_underrun" },
420 { "rx_frags" },
421};
422
423
424#if CP_VLAN_TAG_USED
425static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
426{
427 struct cp_private *cp = netdev_priv(dev);
428 unsigned long flags;
429
430 spin_lock_irqsave(&cp->lock, flags);
431 cp->vlgrp = grp;
Stephen Hemminger7b332242007-06-01 09:43:59 -0700432 if (grp)
433 cp->cpcmd |= RxVlanOn;
434 else
435 cp->cpcmd &= ~RxVlanOn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 cpw16(CpCmd, cp->cpcmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 spin_unlock_irqrestore(&cp->lock, flags);
439}
440#endif /* CP_VLAN_TAG_USED */
441
442static inline void cp_set_rxbufsize (struct cp_private *cp)
443{
444 unsigned int mtu = cp->dev->mtu;
Jeff Garzikf3b197a2006-05-26 21:39:03 -0400445
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 if (mtu > ETH_DATA_LEN)
447 /* MTU + ethernet header + FCS + optional VLAN tag */
448 cp->rx_buf_sz = mtu + ETH_HLEN + 8;
449 else
450 cp->rx_buf_sz = PKT_BUF_SZ;
451}
452
453static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
454 struct cp_desc *desc)
455{
456 skb->protocol = eth_type_trans (skb, cp->dev);
457
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300458 cp->dev->stats.rx_packets++;
459 cp->dev->stats.rx_bytes += skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460
461#if CP_VLAN_TAG_USED
Al Virocf983012007-08-22 21:18:56 -0400462 if (cp->vlgrp && (desc->opts2 & cpu_to_le32(RxVlanTagged))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 vlan_hwaccel_receive_skb(skb, cp->vlgrp,
Al Virocf983012007-08-22 21:18:56 -0400464 swab16(le32_to_cpu(desc->opts2) & 0xffff));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 } else
466#endif
467 netif_receive_skb(skb);
468}
469
470static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
471 u32 status, u32 len)
472{
473 if (netif_msg_rx_err (cp))
Alexander Beregalovb93d5842009-05-26 12:35:27 +0000474 pr_debug("%s: rx err, slot %d status 0x%x len %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 cp->dev->name, rx_tail, status, len);
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300476 cp->dev->stats.rx_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 if (status & RxErrFrame)
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300478 cp->dev->stats.rx_frame_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 if (status & RxErrCRC)
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300480 cp->dev->stats.rx_crc_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 if ((status & RxErrRunt) || (status & RxErrLong))
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300482 cp->dev->stats.rx_length_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag))
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300484 cp->dev->stats.rx_length_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 if (status & RxErrFIFO)
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300486 cp->dev->stats.rx_fifo_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487}
488
489static inline unsigned int cp_rx_csum_ok (u32 status)
490{
491 unsigned int protocol = (status >> 16) & 0x3;
Jeff Garzikf3b197a2006-05-26 21:39:03 -0400492
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 if (likely((protocol == RxProtoTCP) && (!(status & TCPFail))))
494 return 1;
495 else if ((protocol == RxProtoUDP) && (!(status & UDPFail)))
496 return 1;
497 else if ((protocol == RxProtoIP) && (!(status & IPFail)))
498 return 1;
499 return 0;
500}
501
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700502static int cp_rx_poll(struct napi_struct *napi, int budget)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503{
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700504 struct cp_private *cp = container_of(napi, struct cp_private, napi);
505 struct net_device *dev = cp->dev;
506 unsigned int rx_tail = cp->rx_tail;
507 int rx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
509rx_status_loop:
510 rx = 0;
511 cpw16(IntrStatus, cp_rx_intr_mask);
512
513 while (1) {
514 u32 status, len;
515 dma_addr_t mapping;
516 struct sk_buff *skb, *new_skb;
517 struct cp_desc *desc;
Francois Romieu839d1622009-08-12 22:18:14 -0700518 const unsigned buflen = cp->rx_buf_sz;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
Francois Romieu0ba894d2006-08-14 19:55:07 +0200520 skb = cp->rx_skb[rx_tail];
Eric Sesterhenn5d9428d2006-04-02 13:52:48 +0200521 BUG_ON(!skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
523 desc = &cp->rx_ring[rx_tail];
524 status = le32_to_cpu(desc->opts1);
525 if (status & DescOwn)
526 break;
527
528 len = (status & 0x1fff) - 4;
Francois Romieu3598b572006-01-29 01:31:13 +0100529 mapping = le64_to_cpu(desc->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
531 if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) {
532 /* we don't support incoming fragmented frames.
533 * instead, we attempt to ensure that the
534 * pre-allocated RX skbs are properly sized such
535 * that RX fragments are never encountered
536 */
537 cp_rx_err_acct(cp, rx_tail, status, len);
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300538 dev->stats.rx_dropped++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 cp->cp_stats.rx_frags++;
540 goto rx_next;
541 }
542
543 if (status & (RxError | RxErrFIFO)) {
544 cp_rx_err_acct(cp, rx_tail, status, len);
545 goto rx_next;
546 }
547
548 if (netif_msg_rx_status(cp))
Alexander Beregalovb93d5842009-05-26 12:35:27 +0000549 pr_debug("%s: rx slot %d status 0x%x len %d\n",
Francois Romieuc48e9392006-01-29 01:30:48 +0100550 dev->name, rx_tail, status, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551
Francois Romieu839d1622009-08-12 22:18:14 -0700552 new_skb = netdev_alloc_skb(dev, buflen + NET_IP_ALIGN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 if (!new_skb) {
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300554 dev->stats.rx_dropped++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 goto rx_next;
556 }
557
Kevin Loa52be1cbc2008-08-27 11:35:15 +0800558 skb_reserve(new_skb, NET_IP_ALIGN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559
Jeff Garzik6cc92cd2007-08-08 02:16:04 -0400560 dma_unmap_single(&cp->pdev->dev, mapping,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 buflen, PCI_DMA_FROMDEVICE);
562
563 /* Handle checksum offloading for incoming packets. */
564 if (cp_rx_csum_ok(status))
565 skb->ip_summed = CHECKSUM_UNNECESSARY;
566 else
567 skb->ip_summed = CHECKSUM_NONE;
568
569 skb_put(skb, len);
570
Jeff Garzik6cc92cd2007-08-08 02:16:04 -0400571 mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen,
Francois Romieu3598b572006-01-29 01:31:13 +0100572 PCI_DMA_FROMDEVICE);
Francois Romieu0ba894d2006-08-14 19:55:07 +0200573 cp->rx_skb[rx_tail] = new_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574
575 cp_rx_skb(cp, skb, desc);
576 rx++;
577
578rx_next:
579 cp->rx_ring[rx_tail].opts2 = 0;
580 cp->rx_ring[rx_tail].addr = cpu_to_le64(mapping);
581 if (rx_tail == (CP_RX_RING_SIZE - 1))
582 desc->opts1 = cpu_to_le32(DescOwn | RingEnd |
583 cp->rx_buf_sz);
584 else
585 desc->opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz);
586 rx_tail = NEXT_RX(rx_tail);
587
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700588 if (rx >= budget)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 break;
590 }
591
592 cp->rx_tail = rx_tail;
593
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 /* if we did not reach work limit, then we're done with
595 * this round of polling
596 */
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700597 if (rx < budget) {
Francois Romieud15e9c42006-12-17 23:03:15 +0100598 unsigned long flags;
599
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 if (cpr16(IntrStatus) & cp_rx_intr_mask)
601 goto rx_status_loop;
602
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700603 spin_lock_irqsave(&cp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 cpw16_f(IntrMask, cp_intr_mask);
Ben Hutchings288379f2009-01-19 16:43:59 -0800605 __napi_complete(napi);
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700606 spin_unlock_irqrestore(&cp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 }
608
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700609 return rx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610}
611
David Howells7d12e782006-10-05 14:55:46 +0100612static irqreturn_t cp_interrupt (int irq, void *dev_instance)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613{
614 struct net_device *dev = dev_instance;
615 struct cp_private *cp;
616 u16 status;
617
618 if (unlikely(dev == NULL))
619 return IRQ_NONE;
620 cp = netdev_priv(dev);
621
622 status = cpr16(IntrStatus);
623 if (!status || (status == 0xFFFF))
624 return IRQ_NONE;
625
626 if (netif_msg_intr(cp))
Alexander Beregalovb93d5842009-05-26 12:35:27 +0000627 pr_debug("%s: intr, status %04x cmd %02x cpcmd %04x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 dev->name, status, cpr8(Cmd), cpr16(CpCmd));
629
630 cpw16(IntrStatus, status & ~cp_rx_intr_mask);
631
632 spin_lock(&cp->lock);
633
634 /* close possible race's with dev_close */
635 if (unlikely(!netif_running(dev))) {
636 cpw16(IntrMask, 0);
637 spin_unlock(&cp->lock);
638 return IRQ_HANDLED;
639 }
640
641 if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
Ben Hutchings288379f2009-01-19 16:43:59 -0800642 if (napi_schedule_prep(&cp->napi)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 cpw16_f(IntrMask, cp_norx_intr_mask);
Ben Hutchings288379f2009-01-19 16:43:59 -0800644 __napi_schedule(&cp->napi);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 }
646
647 if (status & (TxOK | TxErr | TxEmpty | SWInt))
648 cp_tx(cp);
649 if (status & LinkChg)
Richard Knutsson2501f842007-05-19 22:26:40 +0200650 mii_check_media(&cp->mii_if, netif_msg_link(cp), false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651
652 spin_unlock(&cp->lock);
653
654 if (status & PciErr) {
655 u16 pci_status;
656
657 pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
658 pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
Alexander Beregalovb93d5842009-05-26 12:35:27 +0000659 pr_err("%s: PCI bus error, status=%04x, PCI status=%04x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 dev->name, status, pci_status);
661
662 /* TODO: reset hardware */
663 }
664
665 return IRQ_HANDLED;
666}
667
Steffen Klassert7502cd12005-05-12 19:34:31 -0400668#ifdef CONFIG_NET_POLL_CONTROLLER
669/*
670 * Polling receive - used by netconsole and other diagnostic tools
671 * to allow network i/o with interrupts disabled.
672 */
673static void cp_poll_controller(struct net_device *dev)
674{
675 disable_irq(dev->irq);
David Howells7d12e782006-10-05 14:55:46 +0100676 cp_interrupt(dev->irq, dev);
Steffen Klassert7502cd12005-05-12 19:34:31 -0400677 enable_irq(dev->irq);
678}
679#endif
680
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681static void cp_tx (struct cp_private *cp)
682{
683 unsigned tx_head = cp->tx_head;
684 unsigned tx_tail = cp->tx_tail;
685
686 while (tx_tail != tx_head) {
Francois Romieu3598b572006-01-29 01:31:13 +0100687 struct cp_desc *txd = cp->tx_ring + tx_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 struct sk_buff *skb;
689 u32 status;
690
691 rmb();
Francois Romieu3598b572006-01-29 01:31:13 +0100692 status = le32_to_cpu(txd->opts1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 if (status & DescOwn)
694 break;
695
Francois Romieu48907e32006-09-10 23:33:44 +0200696 skb = cp->tx_skb[tx_tail];
Eric Sesterhenn5d9428d2006-04-02 13:52:48 +0200697 BUG_ON(!skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698
Jeff Garzik6cc92cd2007-08-08 02:16:04 -0400699 dma_unmap_single(&cp->pdev->dev, le64_to_cpu(txd->addr),
Francois Romieu48907e32006-09-10 23:33:44 +0200700 le32_to_cpu(txd->opts1) & 0xffff,
701 PCI_DMA_TODEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702
703 if (status & LastFrag) {
704 if (status & (TxError | TxFIFOUnder)) {
705 if (netif_msg_tx_err(cp))
Alexander Beregalovb93d5842009-05-26 12:35:27 +0000706 pr_debug("%s: tx err, status 0x%x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 cp->dev->name, status);
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300708 cp->dev->stats.tx_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 if (status & TxOWC)
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300710 cp->dev->stats.tx_window_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 if (status & TxMaxCol)
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300712 cp->dev->stats.tx_aborted_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 if (status & TxLinkFail)
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300714 cp->dev->stats.tx_carrier_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 if (status & TxFIFOUnder)
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300716 cp->dev->stats.tx_fifo_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 } else {
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300718 cp->dev->stats.collisions +=
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 ((status >> TxColCntShift) & TxColCntMask);
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300720 cp->dev->stats.tx_packets++;
721 cp->dev->stats.tx_bytes += skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 if (netif_msg_tx_done(cp))
Alexander Beregalovb93d5842009-05-26 12:35:27 +0000723 pr_debug("%s: tx done, slot %d\n", cp->dev->name, tx_tail);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 }
725 dev_kfree_skb_irq(skb);
726 }
727
Francois Romieu48907e32006-09-10 23:33:44 +0200728 cp->tx_skb[tx_tail] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729
730 tx_tail = NEXT_TX(tx_tail);
731 }
732
733 cp->tx_tail = tx_tail;
734
735 if (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1))
736 netif_wake_queue(cp->dev);
737}
738
739static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
740{
741 struct cp_private *cp = netdev_priv(dev);
742 unsigned entry;
Jeff Garzikfcec3452005-05-12 19:28:49 -0400743 u32 eor, flags;
Chris Lalancette553af562007-01-16 16:41:44 -0500744 unsigned long intr_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745#if CP_VLAN_TAG_USED
746 u32 vlan_tag = 0;
747#endif
Jeff Garzikfcec3452005-05-12 19:28:49 -0400748 int mss = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749
Chris Lalancette553af562007-01-16 16:41:44 -0500750 spin_lock_irqsave(&cp->lock, intr_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751
752 /* This is a hard error, log it. */
753 if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
754 netif_stop_queue(dev);
Chris Lalancette553af562007-01-16 16:41:44 -0500755 spin_unlock_irqrestore(&cp->lock, intr_flags);
Alexander Beregalovb93d5842009-05-26 12:35:27 +0000756 pr_err(PFX "%s: BUG! Tx Ring full when queue awake!\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 dev->name);
Patrick McHardy5b548142009-06-12 06:22:29 +0000758 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 }
760
761#if CP_VLAN_TAG_USED
762 if (cp->vlgrp && vlan_tx_tag_present(skb))
Al Virocf983012007-08-22 21:18:56 -0400763 vlan_tag = TxVlanTag | swab16(vlan_tx_tag_get(skb));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764#endif
765
766 entry = cp->tx_head;
767 eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
Jeff Garzikfcec3452005-05-12 19:28:49 -0400768 if (dev->features & NETIF_F_TSO)
Herbert Xu79671682006-06-22 02:40:14 -0700769 mss = skb_shinfo(skb)->gso_size;
Jeff Garzikfcec3452005-05-12 19:28:49 -0400770
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 if (skb_shinfo(skb)->nr_frags == 0) {
772 struct cp_desc *txd = &cp->tx_ring[entry];
773 u32 len;
774 dma_addr_t mapping;
775
776 len = skb->len;
Jeff Garzik6cc92cd2007-08-08 02:16:04 -0400777 mapping = dma_map_single(&cp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 CP_VLAN_TX_TAG(txd, vlan_tag);
779 txd->addr = cpu_to_le64(mapping);
780 wmb();
781
Jeff Garzikfcec3452005-05-12 19:28:49 -0400782 flags = eor | len | DescOwn | FirstFrag | LastFrag;
783
784 if (mss)
785 flags |= LargeSend | ((mss & MSSMask) << MSSShift);
Patrick McHardy84fa7932006-08-29 16:44:56 -0700786 else if (skb->ip_summed == CHECKSUM_PARTIAL) {
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700787 const struct iphdr *ip = ip_hdr(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 if (ip->protocol == IPPROTO_TCP)
Jeff Garzikfcec3452005-05-12 19:28:49 -0400789 flags |= IPCS | TCPCS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 else if (ip->protocol == IPPROTO_UDP)
Jeff Garzikfcec3452005-05-12 19:28:49 -0400791 flags |= IPCS | UDPCS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 else
Francois Romieu57344182005-05-12 19:31:31 -0400793 WARN_ON(1); /* we need a WARN() */
Jeff Garzikfcec3452005-05-12 19:28:49 -0400794 }
795
796 txd->opts1 = cpu_to_le32(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 wmb();
798
Francois Romieu48907e32006-09-10 23:33:44 +0200799 cp->tx_skb[entry] = skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 entry = NEXT_TX(entry);
801 } else {
802 struct cp_desc *txd;
803 u32 first_len, first_eor;
804 dma_addr_t first_mapping;
805 int frag, first_entry = entry;
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700806 const struct iphdr *ip = ip_hdr(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807
808 /* We must give this initial chunk to the device last.
809 * Otherwise we could race with the device.
810 */
811 first_eor = eor;
812 first_len = skb_headlen(skb);
Jeff Garzik6cc92cd2007-08-08 02:16:04 -0400813 first_mapping = dma_map_single(&cp->pdev->dev, skb->data,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 first_len, PCI_DMA_TODEVICE);
Francois Romieu48907e32006-09-10 23:33:44 +0200815 cp->tx_skb[entry] = skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 entry = NEXT_TX(entry);
817
818 for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
819 skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
820 u32 len;
821 u32 ctrl;
822 dma_addr_t mapping;
823
824 len = this_frag->size;
Jeff Garzik6cc92cd2007-08-08 02:16:04 -0400825 mapping = dma_map_single(&cp->pdev->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 ((void *) page_address(this_frag->page) +
827 this_frag->page_offset),
828 len, PCI_DMA_TODEVICE);
829 eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
830
Jeff Garzikfcec3452005-05-12 19:28:49 -0400831 ctrl = eor | len | DescOwn;
832
833 if (mss)
834 ctrl |= LargeSend |
835 ((mss & MSSMask) << MSSShift);
Patrick McHardy84fa7932006-08-29 16:44:56 -0700836 else if (skb->ip_summed == CHECKSUM_PARTIAL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 if (ip->protocol == IPPROTO_TCP)
Jeff Garzikfcec3452005-05-12 19:28:49 -0400838 ctrl |= IPCS | TCPCS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 else if (ip->protocol == IPPROTO_UDP)
Jeff Garzikfcec3452005-05-12 19:28:49 -0400840 ctrl |= IPCS | UDPCS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 else
842 BUG();
Jeff Garzikfcec3452005-05-12 19:28:49 -0400843 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844
845 if (frag == skb_shinfo(skb)->nr_frags - 1)
846 ctrl |= LastFrag;
847
848 txd = &cp->tx_ring[entry];
849 CP_VLAN_TX_TAG(txd, vlan_tag);
850 txd->addr = cpu_to_le64(mapping);
851 wmb();
852
853 txd->opts1 = cpu_to_le32(ctrl);
854 wmb();
855
Francois Romieu48907e32006-09-10 23:33:44 +0200856 cp->tx_skb[entry] = skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 entry = NEXT_TX(entry);
858 }
859
860 txd = &cp->tx_ring[first_entry];
861 CP_VLAN_TX_TAG(txd, vlan_tag);
862 txd->addr = cpu_to_le64(first_mapping);
863 wmb();
864
Patrick McHardy84fa7932006-08-29 16:44:56 -0700865 if (skb->ip_summed == CHECKSUM_PARTIAL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 if (ip->protocol == IPPROTO_TCP)
867 txd->opts1 = cpu_to_le32(first_eor | first_len |
868 FirstFrag | DescOwn |
869 IPCS | TCPCS);
870 else if (ip->protocol == IPPROTO_UDP)
871 txd->opts1 = cpu_to_le32(first_eor | first_len |
872 FirstFrag | DescOwn |
873 IPCS | UDPCS);
874 else
875 BUG();
876 } else
877 txd->opts1 = cpu_to_le32(first_eor | first_len |
878 FirstFrag | DescOwn);
879 wmb();
880 }
881 cp->tx_head = entry;
882 if (netif_msg_tx_queued(cp))
Alexander Beregalovb93d5842009-05-26 12:35:27 +0000883 pr_debug("%s: tx queued, slot %d, skblen %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 dev->name, entry, skb->len);
885 if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
886 netif_stop_queue(dev);
887
Chris Lalancette553af562007-01-16 16:41:44 -0500888 spin_unlock_irqrestore(&cp->lock, intr_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889
890 cpw8(TxPoll, NormalTxPoll);
891 dev->trans_start = jiffies;
892
893 return 0;
894}
895
896/* Set or clear the multicast filter for this adaptor.
897 This routine is not state sensitive and need not be SMP locked. */
898
899static void __cp_set_rx_mode (struct net_device *dev)
900{
901 struct cp_private *cp = netdev_priv(dev);
902 u32 mc_filter[2]; /* Multicast hash filter */
903 int i, rx_mode;
904 u32 tmp;
905
906 /* Note: do not reorder, GCC is clever about common statements. */
907 if (dev->flags & IFF_PROMISC) {
908 /* Unconditionally log net taps. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 rx_mode =
910 AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
911 AcceptAllPhys;
912 mc_filter[1] = mc_filter[0] = 0xffffffff;
913 } else if ((dev->mc_count > multicast_filter_limit)
914 || (dev->flags & IFF_ALLMULTI)) {
915 /* Too many to filter perfectly -- accept all multicasts. */
916 rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
917 mc_filter[1] = mc_filter[0] = 0xffffffff;
918 } else {
919 struct dev_mc_list *mclist;
920 rx_mode = AcceptBroadcast | AcceptMyPhys;
921 mc_filter[1] = mc_filter[0] = 0;
922 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
923 i++, mclist = mclist->next) {
924 int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
925
926 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
927 rx_mode |= AcceptMulticast;
928 }
929 }
930
931 /* We can safely update without stopping the chip. */
932 tmp = cp_rx_config | rx_mode;
933 if (cp->rx_config != tmp) {
934 cpw32_f (RxConfig, tmp);
935 cp->rx_config = tmp;
936 }
937 cpw32_f (MAR0 + 0, mc_filter[0]);
938 cpw32_f (MAR0 + 4, mc_filter[1]);
939}
940
941static void cp_set_rx_mode (struct net_device *dev)
942{
943 unsigned long flags;
944 struct cp_private *cp = netdev_priv(dev);
945
946 spin_lock_irqsave (&cp->lock, flags);
947 __cp_set_rx_mode(dev);
948 spin_unlock_irqrestore (&cp->lock, flags);
949}
950
951static void __cp_get_stats(struct cp_private *cp)
952{
953 /* only lower 24 bits valid; write any value to clear */
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300954 cp->dev->stats.rx_missed_errors += (cpr32 (RxMissed) & 0xffffff);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 cpw32 (RxMissed, 0);
956}
957
958static struct net_device_stats *cp_get_stats(struct net_device *dev)
959{
960 struct cp_private *cp = netdev_priv(dev);
961 unsigned long flags;
962
963 /* The chip only need report frame silently dropped. */
964 spin_lock_irqsave(&cp->lock, flags);
965 if (netif_running(dev) && netif_device_present(dev))
966 __cp_get_stats(cp);
967 spin_unlock_irqrestore(&cp->lock, flags);
968
Paulius Zaleckas237225f2008-05-05 16:05:17 +0300969 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970}
971
972static void cp_stop_hw (struct cp_private *cp)
973{
974 cpw16(IntrStatus, ~(cpr16(IntrStatus)));
975 cpw16_f(IntrMask, 0);
976 cpw8(Cmd, 0);
977 cpw16_f(CpCmd, 0);
978 cpw16_f(IntrStatus, ~(cpr16(IntrStatus)));
979
980 cp->rx_tail = 0;
981 cp->tx_head = cp->tx_tail = 0;
982}
983
984static void cp_reset_hw (struct cp_private *cp)
985{
986 unsigned work = 1000;
987
988 cpw8(Cmd, CmdReset);
989
990 while (work--) {
991 if (!(cpr8(Cmd) & CmdReset))
992 return;
993
Nishanth Aravamudan3173c892005-09-11 02:09:55 -0700994 schedule_timeout_uninterruptible(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 }
996
Alexander Beregalovb93d5842009-05-26 12:35:27 +0000997 pr_err("%s: hardware reset timeout\n", cp->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998}
999
1000static inline void cp_start_hw (struct cp_private *cp)
1001{
1002 cpw16(CpCmd, cp->cpcmd);
1003 cpw8(Cmd, RxOn | TxOn);
1004}
1005
1006static void cp_init_hw (struct cp_private *cp)
1007{
1008 struct net_device *dev = cp->dev;
1009 dma_addr_t ring_dma;
1010
1011 cp_reset_hw(cp);
1012
1013 cpw8_f (Cfg9346, Cfg9346_Unlock);
1014
1015 /* Restore our idea of the MAC address. */
Al Viro03233b92007-08-23 02:31:17 +01001016 cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
1017 cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
1019 cp_start_hw(cp);
1020 cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
1021
1022 __cp_set_rx_mode(dev);
1023 cpw32_f (TxConfig, IFG | (TX_DMA_BURST << TxDMAShift));
1024
1025 cpw8(Config1, cpr8(Config1) | DriverLoaded | PMEnable);
1026 /* Disable Wake-on-LAN. Can be turned on with ETHTOOL_SWOL */
1027 cpw8(Config3, PARMEnable);
1028 cp->wol_enabled = 0;
1029
Jeff Garzikf3b197a2006-05-26 21:39:03 -04001030 cpw8(Config5, cpr8(Config5) & PMEStatus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
1032 cpw32_f(HiTxRingAddr, 0);
1033 cpw32_f(HiTxRingAddr + 4, 0);
1034
1035 ring_dma = cp->ring_dma;
1036 cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
1037 cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
1038
1039 ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
1040 cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
1041 cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
1042
1043 cpw16(MultiIntr, 0);
1044
1045 cpw16_f(IntrMask, cp_intr_mask);
1046
1047 cpw8_f(Cfg9346, Cfg9346_Lock);
1048}
1049
Kevin Loa52be1cbc2008-08-27 11:35:15 +08001050static int cp_refill_rx(struct cp_private *cp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051{
Kevin Loa52be1cbc2008-08-27 11:35:15 +08001052 struct net_device *dev = cp->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 unsigned i;
1054
1055 for (i = 0; i < CP_RX_RING_SIZE; i++) {
1056 struct sk_buff *skb;
Francois Romieu3598b572006-01-29 01:31:13 +01001057 dma_addr_t mapping;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
Kevin Loa52be1cbc2008-08-27 11:35:15 +08001059 skb = netdev_alloc_skb(dev, cp->rx_buf_sz + NET_IP_ALIGN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 if (!skb)
1061 goto err_out;
1062
Kevin Loa52be1cbc2008-08-27 11:35:15 +08001063 skb_reserve(skb, NET_IP_ALIGN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
Jeff Garzik6cc92cd2007-08-08 02:16:04 -04001065 mapping = dma_map_single(&cp->pdev->dev, skb->data,
1066 cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
Francois Romieu0ba894d2006-08-14 19:55:07 +02001067 cp->rx_skb[i] = skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
1069 cp->rx_ring[i].opts2 = 0;
Francois Romieu3598b572006-01-29 01:31:13 +01001070 cp->rx_ring[i].addr = cpu_to_le64(mapping);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 if (i == (CP_RX_RING_SIZE - 1))
1072 cp->rx_ring[i].opts1 =
1073 cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz);
1074 else
1075 cp->rx_ring[i].opts1 =
1076 cpu_to_le32(DescOwn | cp->rx_buf_sz);
1077 }
1078
1079 return 0;
1080
1081err_out:
1082 cp_clean_rings(cp);
1083 return -ENOMEM;
1084}
1085
Francois Romieu576cfa92006-02-27 23:15:06 +01001086static void cp_init_rings_index (struct cp_private *cp)
1087{
1088 cp->rx_tail = 0;
1089 cp->tx_head = cp->tx_tail = 0;
1090}
1091
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092static int cp_init_rings (struct cp_private *cp)
1093{
1094 memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
1095 cp->tx_ring[CP_TX_RING_SIZE - 1].opts1 = cpu_to_le32(RingEnd);
1096
Francois Romieu576cfa92006-02-27 23:15:06 +01001097 cp_init_rings_index(cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
1099 return cp_refill_rx (cp);
1100}
1101
1102static int cp_alloc_rings (struct cp_private *cp)
1103{
1104 void *mem;
1105
Jeff Garzik6cc92cd2007-08-08 02:16:04 -04001106 mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES,
1107 &cp->ring_dma, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 if (!mem)
1109 return -ENOMEM;
1110
1111 cp->rx_ring = mem;
1112 cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE];
1113
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 return cp_init_rings(cp);
1115}
1116
1117static void cp_clean_rings (struct cp_private *cp)
1118{
Francois Romieu3598b572006-01-29 01:31:13 +01001119 struct cp_desc *desc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 unsigned i;
1121
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 for (i = 0; i < CP_RX_RING_SIZE; i++) {
Francois Romieu0ba894d2006-08-14 19:55:07 +02001123 if (cp->rx_skb[i]) {
Francois Romieu3598b572006-01-29 01:31:13 +01001124 desc = cp->rx_ring + i;
Jeff Garzik6cc92cd2007-08-08 02:16:04 -04001125 dma_unmap_single(&cp->pdev->dev,le64_to_cpu(desc->addr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
Francois Romieu0ba894d2006-08-14 19:55:07 +02001127 dev_kfree_skb(cp->rx_skb[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 }
1129 }
1130
1131 for (i = 0; i < CP_TX_RING_SIZE; i++) {
Francois Romieu48907e32006-09-10 23:33:44 +02001132 if (cp->tx_skb[i]) {
1133 struct sk_buff *skb = cp->tx_skb[i];
Francois Romieu57344182005-05-12 19:31:31 -04001134
Francois Romieu3598b572006-01-29 01:31:13 +01001135 desc = cp->tx_ring + i;
Jeff Garzik6cc92cd2007-08-08 02:16:04 -04001136 dma_unmap_single(&cp->pdev->dev,le64_to_cpu(desc->addr),
Francois Romieu48907e32006-09-10 23:33:44 +02001137 le32_to_cpu(desc->opts1) & 0xffff,
1138 PCI_DMA_TODEVICE);
Francois Romieu3598b572006-01-29 01:31:13 +01001139 if (le32_to_cpu(desc->opts1) & LastFrag)
Francois Romieu57344182005-05-12 19:31:31 -04001140 dev_kfree_skb(skb);
Paulius Zaleckas237225f2008-05-05 16:05:17 +03001141 cp->dev->stats.tx_dropped++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 }
1143 }
1144
Francois Romieu57344182005-05-12 19:31:31 -04001145 memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
1146 memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
1147
Francois Romieu0ba894d2006-08-14 19:55:07 +02001148 memset(cp->rx_skb, 0, sizeof(struct sk_buff *) * CP_RX_RING_SIZE);
Francois Romieu48907e32006-09-10 23:33:44 +02001149 memset(cp->tx_skb, 0, sizeof(struct sk_buff *) * CP_TX_RING_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150}
1151
1152static void cp_free_rings (struct cp_private *cp)
1153{
1154 cp_clean_rings(cp);
Jeff Garzik6cc92cd2007-08-08 02:16:04 -04001155 dma_free_coherent(&cp->pdev->dev, CP_RING_BYTES, cp->rx_ring,
1156 cp->ring_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 cp->rx_ring = NULL;
1158 cp->tx_ring = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159}
1160
1161static int cp_open (struct net_device *dev)
1162{
1163 struct cp_private *cp = netdev_priv(dev);
1164 int rc;
1165
1166 if (netif_msg_ifup(cp))
Alexander Beregalovb93d5842009-05-26 12:35:27 +00001167 pr_debug("%s: enabling interface\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
1169 rc = cp_alloc_rings(cp);
1170 if (rc)
1171 return rc;
1172
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001173 napi_enable(&cp->napi);
1174
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 cp_init_hw(cp);
1176
Thomas Gleixner1fb9df52006-07-01 19:29:39 -07001177 rc = request_irq(dev->irq, cp_interrupt, IRQF_SHARED, dev->name, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 if (rc)
1179 goto err_out_hw;
1180
1181 netif_carrier_off(dev);
Richard Knutsson2501f842007-05-19 22:26:40 +02001182 mii_check_media(&cp->mii_if, netif_msg_link(cp), true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 netif_start_queue(dev);
1184
1185 return 0;
1186
1187err_out_hw:
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001188 napi_disable(&cp->napi);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 cp_stop_hw(cp);
1190 cp_free_rings(cp);
1191 return rc;
1192}
1193
1194static int cp_close (struct net_device *dev)
1195{
1196 struct cp_private *cp = netdev_priv(dev);
1197 unsigned long flags;
1198
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001199 napi_disable(&cp->napi);
1200
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 if (netif_msg_ifdown(cp))
Alexander Beregalovb93d5842009-05-26 12:35:27 +00001202 pr_debug("%s: disabling interface\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
1204 spin_lock_irqsave(&cp->lock, flags);
1205
1206 netif_stop_queue(dev);
1207 netif_carrier_off(dev);
1208
1209 cp_stop_hw(cp);
1210
1211 spin_unlock_irqrestore(&cp->lock, flags);
1212
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 free_irq(dev->irq, dev);
1214
1215 cp_free_rings(cp);
1216 return 0;
1217}
1218
Francois Romieu9030c0d2007-07-13 23:05:35 +02001219static void cp_tx_timeout(struct net_device *dev)
1220{
1221 struct cp_private *cp = netdev_priv(dev);
1222 unsigned long flags;
1223 int rc;
1224
Alexander Beregalovb93d5842009-05-26 12:35:27 +00001225 pr_warning("%s: Transmit timeout, status %2x %4x %4x %4x\n",
Francois Romieu9030c0d2007-07-13 23:05:35 +02001226 dev->name, cpr8(Cmd), cpr16(CpCmd),
1227 cpr16(IntrStatus), cpr16(IntrMask));
1228
1229 spin_lock_irqsave(&cp->lock, flags);
1230
1231 cp_stop_hw(cp);
1232 cp_clean_rings(cp);
1233 rc = cp_init_rings(cp);
1234 cp_start_hw(cp);
1235
1236 netif_wake_queue(dev);
1237
1238 spin_unlock_irqrestore(&cp->lock, flags);
1239
1240 return;
1241}
1242
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243#ifdef BROKEN
1244static int cp_change_mtu(struct net_device *dev, int new_mtu)
1245{
1246 struct cp_private *cp = netdev_priv(dev);
1247 int rc;
1248 unsigned long flags;
1249
1250 /* check for invalid MTU, according to hardware limits */
1251 if (new_mtu < CP_MIN_MTU || new_mtu > CP_MAX_MTU)
1252 return -EINVAL;
1253
1254 /* if network interface not up, no need for complexity */
1255 if (!netif_running(dev)) {
1256 dev->mtu = new_mtu;
1257 cp_set_rxbufsize(cp); /* set new rx buf size */
1258 return 0;
1259 }
1260
1261 spin_lock_irqsave(&cp->lock, flags);
1262
1263 cp_stop_hw(cp); /* stop h/w and free rings */
1264 cp_clean_rings(cp);
1265
1266 dev->mtu = new_mtu;
1267 cp_set_rxbufsize(cp); /* set new rx buf size */
1268
1269 rc = cp_init_rings(cp); /* realloc and restart h/w */
1270 cp_start_hw(cp);
1271
1272 spin_unlock_irqrestore(&cp->lock, flags);
1273
1274 return rc;
1275}
1276#endif /* BROKEN */
1277
Arjan van de Venf71e1302006-03-03 21:33:57 -05001278static const char mii_2_8139_map[8] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 BasicModeCtrl,
1280 BasicModeStatus,
1281 0,
1282 0,
1283 NWayAdvert,
1284 NWayLPAR,
1285 NWayExpansion,
1286 0
1287};
1288
1289static int mdio_read(struct net_device *dev, int phy_id, int location)
1290{
1291 struct cp_private *cp = netdev_priv(dev);
1292
1293 return location < 8 && mii_2_8139_map[location] ?
1294 readw(cp->regs + mii_2_8139_map[location]) : 0;
1295}
1296
1297
1298static void mdio_write(struct net_device *dev, int phy_id, int location,
1299 int value)
1300{
1301 struct cp_private *cp = netdev_priv(dev);
1302
1303 if (location == 0) {
1304 cpw8(Cfg9346, Cfg9346_Unlock);
1305 cpw16(BasicModeCtrl, value);
1306 cpw8(Cfg9346, Cfg9346_Lock);
1307 } else if (location < 8 && mii_2_8139_map[location])
1308 cpw16(mii_2_8139_map[location], value);
1309}
1310
1311/* Set the ethtool Wake-on-LAN settings */
1312static int netdev_set_wol (struct cp_private *cp,
1313 const struct ethtool_wolinfo *wol)
1314{
1315 u8 options;
1316
1317 options = cpr8 (Config3) & ~(LinkUp | MagicPacket);
1318 /* If WOL is being disabled, no need for complexity */
1319 if (wol->wolopts) {
1320 if (wol->wolopts & WAKE_PHY) options |= LinkUp;
1321 if (wol->wolopts & WAKE_MAGIC) options |= MagicPacket;
1322 }
1323
1324 cpw8 (Cfg9346, Cfg9346_Unlock);
1325 cpw8 (Config3, options);
1326 cpw8 (Cfg9346, Cfg9346_Lock);
1327
1328 options = 0; /* Paranoia setting */
1329 options = cpr8 (Config5) & ~(UWF | MWF | BWF);
1330 /* If WOL is being disabled, no need for complexity */
1331 if (wol->wolopts) {
1332 if (wol->wolopts & WAKE_UCAST) options |= UWF;
1333 if (wol->wolopts & WAKE_BCAST) options |= BWF;
1334 if (wol->wolopts & WAKE_MCAST) options |= MWF;
1335 }
1336
1337 cpw8 (Config5, options);
1338
1339 cp->wol_enabled = (wol->wolopts) ? 1 : 0;
1340
1341 return 0;
1342}
1343
1344/* Get the ethtool Wake-on-LAN settings */
1345static void netdev_get_wol (struct cp_private *cp,
1346 struct ethtool_wolinfo *wol)
1347{
1348 u8 options;
1349
1350 wol->wolopts = 0; /* Start from scratch */
1351 wol->supported = WAKE_PHY | WAKE_BCAST | WAKE_MAGIC |
1352 WAKE_MCAST | WAKE_UCAST;
1353 /* We don't need to go on if WOL is disabled */
1354 if (!cp->wol_enabled) return;
Jeff Garzikf3b197a2006-05-26 21:39:03 -04001355
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 options = cpr8 (Config3);
1357 if (options & LinkUp) wol->wolopts |= WAKE_PHY;
1358 if (options & MagicPacket) wol->wolopts |= WAKE_MAGIC;
1359
1360 options = 0; /* Paranoia setting */
1361 options = cpr8 (Config5);
1362 if (options & UWF) wol->wolopts |= WAKE_UCAST;
1363 if (options & BWF) wol->wolopts |= WAKE_BCAST;
1364 if (options & MWF) wol->wolopts |= WAKE_MCAST;
1365}
1366
1367static void cp_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info)
1368{
1369 struct cp_private *cp = netdev_priv(dev);
1370
1371 strcpy (info->driver, DRV_NAME);
1372 strcpy (info->version, DRV_VERSION);
1373 strcpy (info->bus_info, pci_name(cp->pdev));
1374}
1375
1376static int cp_get_regs_len(struct net_device *dev)
1377{
1378 return CP_REGS_SIZE;
1379}
1380
Jeff Garzikb9f2c042007-10-03 18:07:32 -07001381static int cp_get_sset_count (struct net_device *dev, int sset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382{
Jeff Garzikb9f2c042007-10-03 18:07:32 -07001383 switch (sset) {
1384 case ETH_SS_STATS:
1385 return CP_NUM_STATS;
1386 default:
1387 return -EOPNOTSUPP;
1388 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389}
1390
1391static int cp_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1392{
1393 struct cp_private *cp = netdev_priv(dev);
1394 int rc;
1395 unsigned long flags;
1396
1397 spin_lock_irqsave(&cp->lock, flags);
1398 rc = mii_ethtool_gset(&cp->mii_if, cmd);
1399 spin_unlock_irqrestore(&cp->lock, flags);
1400
1401 return rc;
1402}
1403
1404static int cp_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1405{
1406 struct cp_private *cp = netdev_priv(dev);
1407 int rc;
1408 unsigned long flags;
1409
1410 spin_lock_irqsave(&cp->lock, flags);
1411 rc = mii_ethtool_sset(&cp->mii_if, cmd);
1412 spin_unlock_irqrestore(&cp->lock, flags);
1413
1414 return rc;
1415}
1416
1417static int cp_nway_reset(struct net_device *dev)
1418{
1419 struct cp_private *cp = netdev_priv(dev);
1420 return mii_nway_restart(&cp->mii_if);
1421}
1422
1423static u32 cp_get_msglevel(struct net_device *dev)
1424{
1425 struct cp_private *cp = netdev_priv(dev);
1426 return cp->msg_enable;
1427}
1428
1429static void cp_set_msglevel(struct net_device *dev, u32 value)
1430{
1431 struct cp_private *cp = netdev_priv(dev);
1432 cp->msg_enable = value;
1433}
1434
1435static u32 cp_get_rx_csum(struct net_device *dev)
1436{
1437 struct cp_private *cp = netdev_priv(dev);
1438 return (cpr16(CpCmd) & RxChkSum) ? 1 : 0;
1439}
1440
1441static int cp_set_rx_csum(struct net_device *dev, u32 data)
1442{
1443 struct cp_private *cp = netdev_priv(dev);
1444 u16 cmd = cp->cpcmd, newcmd;
1445
1446 newcmd = cmd;
1447
1448 if (data)
1449 newcmd |= RxChkSum;
1450 else
1451 newcmd &= ~RxChkSum;
1452
1453 if (newcmd != cmd) {
1454 unsigned long flags;
1455
1456 spin_lock_irqsave(&cp->lock, flags);
1457 cp->cpcmd = newcmd;
1458 cpw16_f(CpCmd, newcmd);
1459 spin_unlock_irqrestore(&cp->lock, flags);
1460 }
1461
1462 return 0;
1463}
1464
1465static void cp_get_regs(struct net_device *dev, struct ethtool_regs *regs,
1466 void *p)
1467{
1468 struct cp_private *cp = netdev_priv(dev);
1469 unsigned long flags;
1470
1471 if (regs->len < CP_REGS_SIZE)
1472 return /* -EINVAL */;
1473
1474 regs->version = CP_REGS_VER;
1475
1476 spin_lock_irqsave(&cp->lock, flags);
1477 memcpy_fromio(p, cp->regs, CP_REGS_SIZE);
1478 spin_unlock_irqrestore(&cp->lock, flags);
1479}
1480
1481static void cp_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
1482{
1483 struct cp_private *cp = netdev_priv(dev);
1484 unsigned long flags;
1485
1486 spin_lock_irqsave (&cp->lock, flags);
1487 netdev_get_wol (cp, wol);
1488 spin_unlock_irqrestore (&cp->lock, flags);
1489}
1490
1491static int cp_set_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
1492{
1493 struct cp_private *cp = netdev_priv(dev);
1494 unsigned long flags;
1495 int rc;
1496
1497 spin_lock_irqsave (&cp->lock, flags);
1498 rc = netdev_set_wol (cp, wol);
1499 spin_unlock_irqrestore (&cp->lock, flags);
1500
1501 return rc;
1502}
1503
1504static void cp_get_strings (struct net_device *dev, u32 stringset, u8 *buf)
1505{
1506 switch (stringset) {
1507 case ETH_SS_STATS:
1508 memcpy(buf, &ethtool_stats_keys, sizeof(ethtool_stats_keys));
1509 break;
1510 default:
1511 BUG();
1512 break;
1513 }
1514}
1515
1516static void cp_get_ethtool_stats (struct net_device *dev,
1517 struct ethtool_stats *estats, u64 *tmp_stats)
1518{
1519 struct cp_private *cp = netdev_priv(dev);
Stephen Hemminger8b512922005-09-14 09:45:44 -07001520 struct cp_dma_stats *nic_stats;
1521 dma_addr_t dma;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 int i;
1523
Jeff Garzik6cc92cd2007-08-08 02:16:04 -04001524 nic_stats = dma_alloc_coherent(&cp->pdev->dev, sizeof(*nic_stats),
1525 &dma, GFP_KERNEL);
Stephen Hemminger8b512922005-09-14 09:45:44 -07001526 if (!nic_stats)
1527 return;
Stephen Hemminger97f568d2005-06-26 18:02:44 -04001528
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 /* begin NIC statistics dump */
Stephen Hemminger8b512922005-09-14 09:45:44 -07001530 cpw32(StatsAddr + 4, (u64)dma >> 32);
Yang Hongyang284901a2009-04-06 19:01:15 -07001531 cpw32(StatsAddr, ((u64)dma & DMA_BIT_MASK(32)) | DumpStats);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 cpr32(StatsAddr);
1533
Stephen Hemminger97f568d2005-06-26 18:02:44 -04001534 for (i = 0; i < 1000; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 if ((cpr32(StatsAddr) & DumpStats) == 0)
1536 break;
Stephen Hemminger97f568d2005-06-26 18:02:44 -04001537 udelay(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 }
Stephen Hemminger97f568d2005-06-26 18:02:44 -04001539 cpw32(StatsAddr, 0);
1540 cpw32(StatsAddr + 4, 0);
Stephen Hemminger8b512922005-09-14 09:45:44 -07001541 cpr32(StatsAddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542
1543 i = 0;
Stephen Hemminger8b512922005-09-14 09:45:44 -07001544 tmp_stats[i++] = le64_to_cpu(nic_stats->tx_ok);
1545 tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok);
1546 tmp_stats[i++] = le64_to_cpu(nic_stats->tx_err);
1547 tmp_stats[i++] = le32_to_cpu(nic_stats->rx_err);
1548 tmp_stats[i++] = le16_to_cpu(nic_stats->rx_fifo);
1549 tmp_stats[i++] = le16_to_cpu(nic_stats->frame_align);
1550 tmp_stats[i++] = le32_to_cpu(nic_stats->tx_ok_1col);
1551 tmp_stats[i++] = le32_to_cpu(nic_stats->tx_ok_mcol);
1552 tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok_phys);
1553 tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok_bcast);
1554 tmp_stats[i++] = le32_to_cpu(nic_stats->rx_ok_mcast);
1555 tmp_stats[i++] = le16_to_cpu(nic_stats->tx_abort);
1556 tmp_stats[i++] = le16_to_cpu(nic_stats->tx_underrun);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 tmp_stats[i++] = cp->cp_stats.rx_frags;
Eric Sesterhenn5d9428d2006-04-02 13:52:48 +02001558 BUG_ON(i != CP_NUM_STATS);
Stephen Hemminger8b512922005-09-14 09:45:44 -07001559
Jeff Garzik6cc92cd2007-08-08 02:16:04 -04001560 dma_free_coherent(&cp->pdev->dev, sizeof(*nic_stats), nic_stats, dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561}
1562
Jeff Garzik7282d492006-09-13 14:30:00 -04001563static const struct ethtool_ops cp_ethtool_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 .get_drvinfo = cp_get_drvinfo,
1565 .get_regs_len = cp_get_regs_len,
Jeff Garzikb9f2c042007-10-03 18:07:32 -07001566 .get_sset_count = cp_get_sset_count,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 .get_settings = cp_get_settings,
1568 .set_settings = cp_set_settings,
1569 .nway_reset = cp_nway_reset,
1570 .get_link = ethtool_op_get_link,
1571 .get_msglevel = cp_get_msglevel,
1572 .set_msglevel = cp_set_msglevel,
1573 .get_rx_csum = cp_get_rx_csum,
1574 .set_rx_csum = cp_set_rx_csum,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 .set_tx_csum = ethtool_op_set_tx_csum, /* local! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 .set_sg = ethtool_op_set_sg,
Jeff Garzikfcec3452005-05-12 19:28:49 -04001577 .set_tso = ethtool_op_set_tso,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 .get_regs = cp_get_regs,
1579 .get_wol = cp_get_wol,
1580 .set_wol = cp_set_wol,
1581 .get_strings = cp_get_strings,
1582 .get_ethtool_stats = cp_get_ethtool_stats,
Philip Craig722fdb32006-06-21 11:33:27 +10001583 .get_eeprom_len = cp_get_eeprom_len,
1584 .get_eeprom = cp_get_eeprom,
1585 .set_eeprom = cp_set_eeprom,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586};
1587
1588static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1589{
1590 struct cp_private *cp = netdev_priv(dev);
1591 int rc;
1592 unsigned long flags;
1593
1594 if (!netif_running(dev))
1595 return -EINVAL;
1596
1597 spin_lock_irqsave(&cp->lock, flags);
1598 rc = generic_mii_ioctl(&cp->mii_if, if_mii(rq), cmd, NULL);
1599 spin_unlock_irqrestore(&cp->lock, flags);
1600 return rc;
1601}
1602
Jiri Pirkoc048aaf2009-03-13 11:47:48 -07001603static int cp_set_mac_address(struct net_device *dev, void *p)
1604{
1605 struct cp_private *cp = netdev_priv(dev);
1606 struct sockaddr *addr = p;
1607
1608 if (!is_valid_ether_addr(addr->sa_data))
1609 return -EADDRNOTAVAIL;
1610
1611 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1612
1613 spin_lock_irq(&cp->lock);
1614
1615 cpw8_f(Cfg9346, Cfg9346_Unlock);
1616 cpw32_f(MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
1617 cpw32_f(MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
1618 cpw8_f(Cfg9346, Cfg9346_Lock);
1619
1620 spin_unlock_irq(&cp->lock);
1621
1622 return 0;
1623}
1624
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625/* Serial EEPROM section. */
1626
1627/* EEPROM_Ctrl bits. */
1628#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */
1629#define EE_CS 0x08 /* EEPROM chip select. */
1630#define EE_DATA_WRITE 0x02 /* EEPROM chip data in. */
1631#define EE_WRITE_0 0x00
1632#define EE_WRITE_1 0x02
1633#define EE_DATA_READ 0x01 /* EEPROM chip data out. */
1634#define EE_ENB (0x80 | EE_CS)
1635
1636/* Delay between EEPROM clock transitions.
1637 No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
1638 */
1639
1640#define eeprom_delay() readl(ee_addr)
1641
1642/* The EEPROM commands include the alway-set leading bit. */
Philip Craig722fdb32006-06-21 11:33:27 +10001643#define EE_EXTEND_CMD (4)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644#define EE_WRITE_CMD (5)
1645#define EE_READ_CMD (6)
1646#define EE_ERASE_CMD (7)
1647
Philip Craig722fdb32006-06-21 11:33:27 +10001648#define EE_EWDS_ADDR (0)
1649#define EE_WRAL_ADDR (1)
1650#define EE_ERAL_ADDR (2)
1651#define EE_EWEN_ADDR (3)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652
Philip Craig722fdb32006-06-21 11:33:27 +10001653#define CP_EEPROM_MAGIC PCI_DEVICE_ID_REALTEK_8139
1654
1655static void eeprom_cmd_start(void __iomem *ee_addr)
1656{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 writeb (EE_ENB & ~EE_CS, ee_addr);
1658 writeb (EE_ENB, ee_addr);
1659 eeprom_delay ();
Philip Craig722fdb32006-06-21 11:33:27 +10001660}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661
Philip Craig722fdb32006-06-21 11:33:27 +10001662static void eeprom_cmd(void __iomem *ee_addr, int cmd, int cmd_len)
1663{
1664 int i;
1665
1666 /* Shift the command bits out. */
1667 for (i = cmd_len - 1; i >= 0; i--) {
1668 int dataval = (cmd & (1 << i)) ? EE_DATA_WRITE : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 writeb (EE_ENB | dataval, ee_addr);
1670 eeprom_delay ();
1671 writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
1672 eeprom_delay ();
1673 }
1674 writeb (EE_ENB, ee_addr);
1675 eeprom_delay ();
Philip Craig722fdb32006-06-21 11:33:27 +10001676}
1677
1678static void eeprom_cmd_end(void __iomem *ee_addr)
1679{
1680 writeb (~EE_CS, ee_addr);
1681 eeprom_delay ();
1682}
1683
1684static void eeprom_extend_cmd(void __iomem *ee_addr, int extend_cmd,
1685 int addr_len)
1686{
1687 int cmd = (EE_EXTEND_CMD << addr_len) | (extend_cmd << (addr_len - 2));
1688
1689 eeprom_cmd_start(ee_addr);
1690 eeprom_cmd(ee_addr, cmd, 3 + addr_len);
1691 eeprom_cmd_end(ee_addr);
1692}
1693
1694static u16 read_eeprom (void __iomem *ioaddr, int location, int addr_len)
1695{
1696 int i;
1697 u16 retval = 0;
1698 void __iomem *ee_addr = ioaddr + Cfg9346;
1699 int read_cmd = location | (EE_READ_CMD << addr_len);
1700
1701 eeprom_cmd_start(ee_addr);
1702 eeprom_cmd(ee_addr, read_cmd, 3 + addr_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703
1704 for (i = 16; i > 0; i--) {
1705 writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
1706 eeprom_delay ();
1707 retval =
1708 (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :
1709 0);
1710 writeb (EE_ENB, ee_addr);
1711 eeprom_delay ();
1712 }
1713
Philip Craig722fdb32006-06-21 11:33:27 +10001714 eeprom_cmd_end(ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715
1716 return retval;
1717}
1718
Philip Craig722fdb32006-06-21 11:33:27 +10001719static void write_eeprom(void __iomem *ioaddr, int location, u16 val,
1720 int addr_len)
1721{
1722 int i;
1723 void __iomem *ee_addr = ioaddr + Cfg9346;
1724 int write_cmd = location | (EE_WRITE_CMD << addr_len);
1725
1726 eeprom_extend_cmd(ee_addr, EE_EWEN_ADDR, addr_len);
1727
1728 eeprom_cmd_start(ee_addr);
1729 eeprom_cmd(ee_addr, write_cmd, 3 + addr_len);
1730 eeprom_cmd(ee_addr, val, 16);
1731 eeprom_cmd_end(ee_addr);
1732
1733 eeprom_cmd_start(ee_addr);
1734 for (i = 0; i < 20000; i++)
1735 if (readb(ee_addr) & EE_DATA_READ)
1736 break;
1737 eeprom_cmd_end(ee_addr);
1738
1739 eeprom_extend_cmd(ee_addr, EE_EWDS_ADDR, addr_len);
1740}
1741
1742static int cp_get_eeprom_len(struct net_device *dev)
1743{
1744 struct cp_private *cp = netdev_priv(dev);
1745 int size;
1746
1747 spin_lock_irq(&cp->lock);
1748 size = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 256 : 128;
1749 spin_unlock_irq(&cp->lock);
1750
1751 return size;
1752}
1753
1754static int cp_get_eeprom(struct net_device *dev,
1755 struct ethtool_eeprom *eeprom, u8 *data)
1756{
1757 struct cp_private *cp = netdev_priv(dev);
1758 unsigned int addr_len;
1759 u16 val;
1760 u32 offset = eeprom->offset >> 1;
1761 u32 len = eeprom->len;
1762 u32 i = 0;
1763
1764 eeprom->magic = CP_EEPROM_MAGIC;
1765
1766 spin_lock_irq(&cp->lock);
1767
1768 addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6;
1769
1770 if (eeprom->offset & 1) {
1771 val = read_eeprom(cp->regs, offset, addr_len);
1772 data[i++] = (u8)(val >> 8);
1773 offset++;
1774 }
1775
1776 while (i < len - 1) {
1777 val = read_eeprom(cp->regs, offset, addr_len);
1778 data[i++] = (u8)val;
1779 data[i++] = (u8)(val >> 8);
1780 offset++;
1781 }
1782
1783 if (i < len) {
1784 val = read_eeprom(cp->regs, offset, addr_len);
1785 data[i] = (u8)val;
1786 }
1787
1788 spin_unlock_irq(&cp->lock);
1789 return 0;
1790}
1791
1792static int cp_set_eeprom(struct net_device *dev,
1793 struct ethtool_eeprom *eeprom, u8 *data)
1794{
1795 struct cp_private *cp = netdev_priv(dev);
1796 unsigned int addr_len;
1797 u16 val;
1798 u32 offset = eeprom->offset >> 1;
1799 u32 len = eeprom->len;
1800 u32 i = 0;
1801
1802 if (eeprom->magic != CP_EEPROM_MAGIC)
1803 return -EINVAL;
1804
1805 spin_lock_irq(&cp->lock);
1806
1807 addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6;
1808
1809 if (eeprom->offset & 1) {
1810 val = read_eeprom(cp->regs, offset, addr_len) & 0xff;
1811 val |= (u16)data[i++] << 8;
1812 write_eeprom(cp->regs, offset, val, addr_len);
1813 offset++;
1814 }
1815
1816 while (i < len - 1) {
1817 val = (u16)data[i++];
1818 val |= (u16)data[i++] << 8;
1819 write_eeprom(cp->regs, offset, val, addr_len);
1820 offset++;
1821 }
1822
1823 if (i < len) {
1824 val = read_eeprom(cp->regs, offset, addr_len) & 0xff00;
1825 val |= (u16)data[i];
1826 write_eeprom(cp->regs, offset, val, addr_len);
1827 }
1828
1829 spin_unlock_irq(&cp->lock);
1830 return 0;
1831}
1832
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833/* Put the board into D3cold state and wait for WakeUp signal */
1834static void cp_set_d3_state (struct cp_private *cp)
1835{
1836 pci_enable_wake (cp->pdev, 0, 1); /* Enable PME# generation */
1837 pci_set_power_state (cp->pdev, PCI_D3hot);
1838}
1839
Stephen Hemminger48dfcde2008-11-19 22:09:07 -08001840static const struct net_device_ops cp_netdev_ops = {
1841 .ndo_open = cp_open,
1842 .ndo_stop = cp_close,
1843 .ndo_validate_addr = eth_validate_addr,
Jiri Pirkoc048aaf2009-03-13 11:47:48 -07001844 .ndo_set_mac_address = cp_set_mac_address,
Stephen Hemminger48dfcde2008-11-19 22:09:07 -08001845 .ndo_set_multicast_list = cp_set_rx_mode,
1846 .ndo_get_stats = cp_get_stats,
1847 .ndo_do_ioctl = cp_ioctl,
Stephen Hemminger00829822008-11-20 20:14:53 -08001848 .ndo_start_xmit = cp_start_xmit,
Stephen Hemminger48dfcde2008-11-19 22:09:07 -08001849 .ndo_tx_timeout = cp_tx_timeout,
1850#if CP_VLAN_TAG_USED
1851 .ndo_vlan_rx_register = cp_vlan_rx_register,
1852#endif
1853#ifdef BROKEN
1854 .ndo_change_mtu = cp_change_mtu,
1855#endif
Stephen Hemmingerfe96aaa2009-01-09 11:13:14 +00001856
Stephen Hemminger48dfcde2008-11-19 22:09:07 -08001857#ifdef CONFIG_NET_POLL_CONTROLLER
1858 .ndo_poll_controller = cp_poll_controller,
1859#endif
1860};
1861
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
1863{
1864 struct net_device *dev;
1865 struct cp_private *cp;
1866 int rc;
1867 void __iomem *regs;
Greg Kroah-Hartman2427ddd2006-06-12 17:07:52 -07001868 resource_size_t pciaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 unsigned int addr_len, i, pci_using_dac;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870
1871#ifndef MODULE
1872 static int version_printed;
1873 if (version_printed++ == 0)
Alexander Beregalovb93d5842009-05-26 12:35:27 +00001874 pr_info("%s", version);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875#endif
1876
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
Auke Kok44c10132007-06-08 15:46:36 -07001878 pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision < 0x20) {
Stephen Hemmingerde4549c2008-10-21 18:04:27 -07001879 dev_info(&pdev->dev,
1880 "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip, use 8139too\n",
Auke Kok44c10132007-06-08 15:46:36 -07001881 pdev->vendor, pdev->device, pdev->revision);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 return -ENODEV;
1883 }
1884
1885 dev = alloc_etherdev(sizeof(struct cp_private));
1886 if (!dev)
1887 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 SET_NETDEV_DEV(dev, &pdev->dev);
1889
1890 cp = netdev_priv(dev);
1891 cp->pdev = pdev;
1892 cp->dev = dev;
1893 cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);
1894 spin_lock_init (&cp->lock);
1895 cp->mii_if.dev = dev;
1896 cp->mii_if.mdio_read = mdio_read;
1897 cp->mii_if.mdio_write = mdio_write;
1898 cp->mii_if.phy_id = CP_INTERNAL_PHY;
1899 cp->mii_if.phy_id_mask = 0x1f;
1900 cp->mii_if.reg_num_mask = 0x1f;
1901 cp_set_rxbufsize(cp);
1902
1903 rc = pci_enable_device(pdev);
1904 if (rc)
1905 goto err_out_free;
1906
1907 rc = pci_set_mwi(pdev);
1908 if (rc)
1909 goto err_out_disable;
1910
1911 rc = pci_request_regions(pdev, DRV_NAME);
1912 if (rc)
1913 goto err_out_mwi;
1914
1915 pciaddr = pci_resource_start(pdev, 1);
1916 if (!pciaddr) {
1917 rc = -EIO;
Jeff Garzik9b91cf92006-06-27 11:39:50 -04001918 dev_err(&pdev->dev, "no MMIO resource\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 goto err_out_res;
1920 }
1921 if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) {
1922 rc = -EIO;
Jeff Garzik9b91cf92006-06-27 11:39:50 -04001923 dev_err(&pdev->dev, "MMIO resource (%llx) too small\n",
Jeff Garzik2e8a5382006-06-27 10:47:51 -04001924 (unsigned long long)pci_resource_len(pdev, 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 goto err_out_res;
1926 }
1927
1928 /* Configure DMA attributes. */
1929 if ((sizeof(dma_addr_t) > 4) &&
Yang Hongyang6a355282009-04-06 19:01:13 -07001930 !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) &&
1931 !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 pci_using_dac = 1;
1933 } else {
1934 pci_using_dac = 0;
1935
Yang Hongyang284901a2009-04-06 19:01:15 -07001936 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 if (rc) {
Jeff Garzik9b91cf92006-06-27 11:39:50 -04001938 dev_err(&pdev->dev,
Jeff Garzik2e8a5382006-06-27 10:47:51 -04001939 "No usable DMA configuration, aborting.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 goto err_out_res;
1941 }
Yang Hongyang284901a2009-04-06 19:01:15 -07001942 rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 if (rc) {
Jeff Garzik9b91cf92006-06-27 11:39:50 -04001944 dev_err(&pdev->dev,
Jeff Garzik2e8a5382006-06-27 10:47:51 -04001945 "No usable consistent DMA configuration, "
1946 "aborting.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 goto err_out_res;
1948 }
1949 }
1950
1951 cp->cpcmd = (pci_using_dac ? PCIDAC : 0) |
1952 PCIMulRW | RxChkSum | CpRxOn | CpTxOn;
1953
1954 regs = ioremap(pciaddr, CP_REGS_SIZE);
1955 if (!regs) {
1956 rc = -EIO;
Andrew Morton4626dd42006-07-06 23:58:26 -07001957 dev_err(&pdev->dev, "Cannot map PCI MMIO (%Lx@%Lx)\n",
Jeff Garzik2e8a5382006-06-27 10:47:51 -04001958 (unsigned long long)pci_resource_len(pdev, 1),
1959 (unsigned long long)pciaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 goto err_out_res;
1961 }
1962 dev->base_addr = (unsigned long) regs;
1963 cp->regs = regs;
1964
1965 cp_stop_hw(cp);
1966
1967 /* read MAC address from EEPROM */
1968 addr_len = read_eeprom (regs, 0, 8) == 0x8129 ? 8 : 6;
1969 for (i = 0; i < 3; i++)
Al Viro03233b92007-08-23 02:31:17 +01001970 ((__le16 *) (dev->dev_addr))[i] =
1971 cpu_to_le16(read_eeprom (regs, i + 7, addr_len));
John W. Linvillebb0ce602005-09-12 10:48:54 -04001972 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973
Stephen Hemminger48dfcde2008-11-19 22:09:07 -08001974 dev->netdev_ops = &cp_netdev_ops;
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001975 netif_napi_add(dev, &cp->napi, cp_rx_poll, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976 dev->ethtool_ops = &cp_ethtool_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 dev->watchdog_timeo = TX_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978
1979#if CP_VLAN_TAG_USED
1980 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981#endif
1982
1983 if (pci_using_dac)
1984 dev->features |= NETIF_F_HIGHDMA;
1985
Jeff Garzikfcec3452005-05-12 19:28:49 -04001986#if 0 /* disabled by default until verified */
1987 dev->features |= NETIF_F_TSO;
1988#endif
1989
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990 dev->irq = pdev->irq;
1991
1992 rc = register_netdev(dev);
1993 if (rc)
1994 goto err_out_iomap;
1995
Alexander Beregalovb93d5842009-05-26 12:35:27 +00001996 pr_info("%s: RTL-8139C+ at 0x%lx, %pM, IRQ %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 dev->name,
1998 dev->base_addr,
Johannes Berge1749612008-10-27 15:59:26 -07001999 dev->dev_addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 dev->irq);
2001
2002 pci_set_drvdata(pdev, dev);
2003
2004 /* enable busmastering and memory-write-invalidate */
2005 pci_set_master(pdev);
2006
Jeff Garzik2e8a5382006-06-27 10:47:51 -04002007 if (cp->wol_enabled)
2008 cp_set_d3_state (cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009
2010 return 0;
2011
2012err_out_iomap:
2013 iounmap(regs);
2014err_out_res:
2015 pci_release_regions(pdev);
2016err_out_mwi:
2017 pci_clear_mwi(pdev);
2018err_out_disable:
2019 pci_disable_device(pdev);
2020err_out_free:
2021 free_netdev(dev);
2022 return rc;
2023}
2024
2025static void cp_remove_one (struct pci_dev *pdev)
2026{
2027 struct net_device *dev = pci_get_drvdata(pdev);
2028 struct cp_private *cp = netdev_priv(dev);
2029
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030 unregister_netdev(dev);
2031 iounmap(cp->regs);
Jeff Garzik2e8a5382006-06-27 10:47:51 -04002032 if (cp->wol_enabled)
2033 pci_set_power_state (pdev, PCI_D0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 pci_release_regions(pdev);
2035 pci_clear_mwi(pdev);
2036 pci_disable_device(pdev);
2037 pci_set_drvdata(pdev, NULL);
2038 free_netdev(dev);
2039}
2040
2041#ifdef CONFIG_PM
Pavel Machek05adc3b2005-04-16 15:25:25 -07002042static int cp_suspend (struct pci_dev *pdev, pm_message_t state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043{
François Romieu7668a492006-08-15 20:10:57 +02002044 struct net_device *dev = pci_get_drvdata(pdev);
2045 struct cp_private *cp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 unsigned long flags;
2047
François Romieu7668a492006-08-15 20:10:57 +02002048 if (!netif_running(dev))
2049 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050
2051 netif_device_detach (dev);
2052 netif_stop_queue (dev);
2053
2054 spin_lock_irqsave (&cp->lock, flags);
2055
2056 /* Disable Rx and Tx */
2057 cpw16 (IntrMask, 0);
2058 cpw8 (Cmd, cpr8 (Cmd) & (~RxOn | ~TxOn));
2059
2060 spin_unlock_irqrestore (&cp->lock, flags);
2061
Francois Romieu576cfa92006-02-27 23:15:06 +01002062 pci_save_state(pdev);
2063 pci_enable_wake(pdev, pci_choose_state(pdev, state), cp->wol_enabled);
2064 pci_set_power_state(pdev, pci_choose_state(pdev, state));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065
2066 return 0;
2067}
2068
2069static int cp_resume (struct pci_dev *pdev)
2070{
Francois Romieu576cfa92006-02-27 23:15:06 +01002071 struct net_device *dev = pci_get_drvdata (pdev);
2072 struct cp_private *cp = netdev_priv(dev);
Pierre Ossmana4cf0762005-07-04 00:22:53 +02002073 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074
Francois Romieu576cfa92006-02-27 23:15:06 +01002075 if (!netif_running(dev))
2076 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077
2078 netif_device_attach (dev);
Francois Romieu576cfa92006-02-27 23:15:06 +01002079
2080 pci_set_power_state(pdev, PCI_D0);
2081 pci_restore_state(pdev);
2082 pci_enable_wake(pdev, PCI_D0, 0);
2083
2084 /* FIXME: sh*t may happen if the Rx ring buffer is depleted */
2085 cp_init_rings_index (cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 cp_init_hw (cp);
2087 netif_start_queue (dev);
Pierre Ossmana4cf0762005-07-04 00:22:53 +02002088
2089 spin_lock_irqsave (&cp->lock, flags);
2090
Richard Knutsson2501f842007-05-19 22:26:40 +02002091 mii_check_media(&cp->mii_if, netif_msg_link(cp), false);
Pierre Ossmana4cf0762005-07-04 00:22:53 +02002092
2093 spin_unlock_irqrestore (&cp->lock, flags);
Jeff Garzikf3b197a2006-05-26 21:39:03 -04002094
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095 return 0;
2096}
2097#endif /* CONFIG_PM */
2098
2099static struct pci_driver cp_driver = {
2100 .name = DRV_NAME,
2101 .id_table = cp_pci_tbl,
2102 .probe = cp_init_one,
2103 .remove = cp_remove_one,
2104#ifdef CONFIG_PM
2105 .resume = cp_resume,
2106 .suspend = cp_suspend,
2107#endif
2108};
2109
2110static int __init cp_init (void)
2111{
2112#ifdef MODULE
Alexander Beregalovb93d5842009-05-26 12:35:27 +00002113 pr_info("%s", version);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114#endif
Jeff Garzik29917622006-08-19 17:48:59 -04002115 return pci_register_driver(&cp_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002116}
2117
2118static void __exit cp_exit (void)
2119{
2120 pci_unregister_driver (&cp_driver);
2121}
2122
2123module_init(cp_init);
2124module_exit(cp_exit);