1a88394cfSJeff Kirsher /* de2104x.c: A Linux PCI Ethernet driver for Intel/Digital 21040/1 chips. */
2a88394cfSJeff Kirsher /*
3a88394cfSJeff Kirsher Copyright 2001,2003 Jeff Garzik <jgarzik@pobox.com>
4a88394cfSJeff Kirsher
5a88394cfSJeff Kirsher Copyright 1994, 1995 Digital Equipment Corporation. [de4x5.c]
6a88394cfSJeff Kirsher Written/copyright 1994-2001 by Donald Becker. [tulip.c]
7a88394cfSJeff Kirsher
8a88394cfSJeff Kirsher This software may be used and distributed according to the terms of
9a88394cfSJeff Kirsher the GNU General Public License (GPL), incorporated herein by reference.
10a88394cfSJeff Kirsher Drivers based on or derived from this code fall under the GPL and must
11a88394cfSJeff Kirsher retain the authorship, copyright and license notice. This file is not
12a88394cfSJeff Kirsher a complete program and may only be used when the entire operating
13a88394cfSJeff Kirsher system is licensed under the GPL.
14a88394cfSJeff Kirsher
15a88394cfSJeff Kirsher See the file COPYING in this distribution for more information.
16a88394cfSJeff Kirsher
17a88394cfSJeff Kirsher TODO, in rough priority order:
18a88394cfSJeff Kirsher * Support forcing media type with a module parameter,
19a88394cfSJeff Kirsher like dl2k.c/sundance.c
20a88394cfSJeff Kirsher * Constants (module parms?) for Rx work limit
21a88394cfSJeff Kirsher * Complete reset on PciErr
22a88394cfSJeff Kirsher * Jumbo frames / dev->change_mtu
23a88394cfSJeff Kirsher * Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
24a88394cfSJeff Kirsher * Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error
25a88394cfSJeff Kirsher * Implement Tx software interrupt mitigation via
26a88394cfSJeff Kirsher Tx descriptor bit
27a88394cfSJeff Kirsher
28a88394cfSJeff Kirsher */
29a88394cfSJeff Kirsher
30a88394cfSJeff Kirsher #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31a88394cfSJeff Kirsher
32a88394cfSJeff Kirsher #define DRV_NAME "de2104x"
33a88394cfSJeff Kirsher #define DRV_RELDATE "Mar 17, 2004"
34a88394cfSJeff Kirsher
35a88394cfSJeff Kirsher #include <linux/module.h>
36a88394cfSJeff Kirsher #include <linux/kernel.h>
37a88394cfSJeff Kirsher #include <linux/netdevice.h>
38a88394cfSJeff Kirsher #include <linux/etherdevice.h>
39a88394cfSJeff Kirsher #include <linux/init.h>
40a88394cfSJeff Kirsher #include <linux/interrupt.h>
41a88394cfSJeff Kirsher #include <linux/pci.h>
42a88394cfSJeff Kirsher #include <linux/delay.h>
43a88394cfSJeff Kirsher #include <linux/ethtool.h>
44a88394cfSJeff Kirsher #include <linux/compiler.h>
45a88394cfSJeff Kirsher #include <linux/rtnetlink.h>
46a88394cfSJeff Kirsher #include <linux/crc32.h>
47a88394cfSJeff Kirsher #include <linux/slab.h>
48a88394cfSJeff Kirsher
49a88394cfSJeff Kirsher #include <asm/io.h>
50a88394cfSJeff Kirsher #include <asm/irq.h>
517c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
52*5f60d5f6SAl Viro #include <linux/unaligned.h>
53a88394cfSJeff Kirsher
54a88394cfSJeff Kirsher MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
55a88394cfSJeff Kirsher MODULE_DESCRIPTION("Intel/Digital 21040/1 series PCI Ethernet driver");
56a88394cfSJeff Kirsher MODULE_LICENSE("GPL");
57a88394cfSJeff Kirsher
58a88394cfSJeff Kirsher static int debug = -1;
59a88394cfSJeff Kirsher module_param (debug, int, 0);
60a88394cfSJeff Kirsher MODULE_PARM_DESC (debug, "de2104x bitmapped message enable number");
61a88394cfSJeff Kirsher
62a88394cfSJeff Kirsher /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
63a88394cfSJeff Kirsher #if defined(__alpha__) || defined(__arm__) || defined(__hppa__) || \
64a88394cfSJeff Kirsher defined(CONFIG_SPARC) || defined(__ia64__) || \
65a88394cfSJeff Kirsher defined(__sh__) || defined(__mips__)
66a88394cfSJeff Kirsher static int rx_copybreak = 1518;
67a88394cfSJeff Kirsher #else
68a88394cfSJeff Kirsher static int rx_copybreak = 100;
69a88394cfSJeff Kirsher #endif
70a88394cfSJeff Kirsher module_param (rx_copybreak, int, 0);
71a88394cfSJeff Kirsher MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copied");
72a88394cfSJeff Kirsher
73a88394cfSJeff Kirsher #define DE_DEF_MSG_ENABLE (NETIF_MSG_DRV | \
74a88394cfSJeff Kirsher NETIF_MSG_PROBE | \
75a88394cfSJeff Kirsher NETIF_MSG_LINK | \
76a88394cfSJeff Kirsher NETIF_MSG_IFDOWN | \
77a88394cfSJeff Kirsher NETIF_MSG_IFUP | \
78a88394cfSJeff Kirsher NETIF_MSG_RX_ERR | \
79a88394cfSJeff Kirsher NETIF_MSG_TX_ERR)
80a88394cfSJeff Kirsher
81a88394cfSJeff Kirsher /* Descriptor skip length in 32 bit longwords. */
82a88394cfSJeff Kirsher #ifndef CONFIG_DE2104X_DSL
83a88394cfSJeff Kirsher #define DSL 0
84a88394cfSJeff Kirsher #else
85a88394cfSJeff Kirsher #define DSL CONFIG_DE2104X_DSL
86a88394cfSJeff Kirsher #endif
87a88394cfSJeff Kirsher
88ee460417SLucy Yan #define DE_RX_RING_SIZE 128
89a88394cfSJeff Kirsher #define DE_TX_RING_SIZE 64
90a88394cfSJeff Kirsher #define DE_RING_BYTES \
91a88394cfSJeff Kirsher ((sizeof(struct de_desc) * DE_RX_RING_SIZE) + \
92a88394cfSJeff Kirsher (sizeof(struct de_desc) * DE_TX_RING_SIZE))
93a88394cfSJeff Kirsher #define NEXT_TX(N) (((N) + 1) & (DE_TX_RING_SIZE - 1))
94a88394cfSJeff Kirsher #define NEXT_RX(N) (((N) + 1) & (DE_RX_RING_SIZE - 1))
95a88394cfSJeff Kirsher #define TX_BUFFS_AVAIL(CP) \
96a88394cfSJeff Kirsher (((CP)->tx_tail <= (CP)->tx_head) ? \
97a88394cfSJeff Kirsher (CP)->tx_tail + (DE_TX_RING_SIZE - 1) - (CP)->tx_head : \
98a88394cfSJeff Kirsher (CP)->tx_tail - (CP)->tx_head - 1)
99a88394cfSJeff Kirsher
100a88394cfSJeff Kirsher #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
101a88394cfSJeff Kirsher #define RX_OFFSET 2
102a88394cfSJeff Kirsher
103a88394cfSJeff Kirsher #define DE_SETUP_SKB ((struct sk_buff *) 1)
104a88394cfSJeff Kirsher #define DE_DUMMY_SKB ((struct sk_buff *) 2)
105a88394cfSJeff Kirsher #define DE_SETUP_FRAME_WORDS 96
106a88394cfSJeff Kirsher #define DE_EEPROM_WORDS 256
107a88394cfSJeff Kirsher #define DE_EEPROM_SIZE (DE_EEPROM_WORDS * sizeof(u16))
108a88394cfSJeff Kirsher #define DE_MAX_MEDIA 5
109a88394cfSJeff Kirsher
110a88394cfSJeff Kirsher #define DE_MEDIA_TP_AUTO 0
111a88394cfSJeff Kirsher #define DE_MEDIA_BNC 1
112a88394cfSJeff Kirsher #define DE_MEDIA_AUI 2
113a88394cfSJeff Kirsher #define DE_MEDIA_TP 3
114a88394cfSJeff Kirsher #define DE_MEDIA_TP_FD 4
115a88394cfSJeff Kirsher #define DE_MEDIA_INVALID DE_MAX_MEDIA
116a88394cfSJeff Kirsher #define DE_MEDIA_FIRST 0
117a88394cfSJeff Kirsher #define DE_MEDIA_LAST (DE_MAX_MEDIA - 1)
118a88394cfSJeff Kirsher #define DE_AUI_BNC (SUPPORTED_AUI | SUPPORTED_BNC)
119a88394cfSJeff Kirsher
120a88394cfSJeff Kirsher #define DE_TIMER_LINK (60 * HZ)
121a88394cfSJeff Kirsher #define DE_TIMER_NO_LINK (5 * HZ)
122a88394cfSJeff Kirsher
123a88394cfSJeff Kirsher #define DE_NUM_REGS 16
124a88394cfSJeff Kirsher #define DE_REGS_SIZE (DE_NUM_REGS * sizeof(u32))
125a88394cfSJeff Kirsher #define DE_REGS_VER 1
126a88394cfSJeff Kirsher
127a88394cfSJeff Kirsher /* Time in jiffies before concluding the transmitter is hung. */
128a88394cfSJeff Kirsher #define TX_TIMEOUT (6*HZ)
129a88394cfSJeff Kirsher
130a88394cfSJeff Kirsher /* This is a mysterious value that can be written to CSR11 in the 21040 (only)
131a88394cfSJeff Kirsher to support a pre-NWay full-duplex signaling mechanism using short frames.
132a88394cfSJeff Kirsher No one knows what it should be, but if left at its default value some
133a88394cfSJeff Kirsher 10base2(!) packets trigger a full-duplex-request interrupt. */
134a88394cfSJeff Kirsher #define FULL_DUPLEX_MAGIC 0x6969
135a88394cfSJeff Kirsher
136a88394cfSJeff Kirsher enum {
137a88394cfSJeff Kirsher /* NIC registers */
138a88394cfSJeff Kirsher BusMode = 0x00,
139a88394cfSJeff Kirsher TxPoll = 0x08,
140a88394cfSJeff Kirsher RxPoll = 0x10,
141a88394cfSJeff Kirsher RxRingAddr = 0x18,
142a88394cfSJeff Kirsher TxRingAddr = 0x20,
143a88394cfSJeff Kirsher MacStatus = 0x28,
144a88394cfSJeff Kirsher MacMode = 0x30,
145a88394cfSJeff Kirsher IntrMask = 0x38,
146a88394cfSJeff Kirsher RxMissed = 0x40,
147a88394cfSJeff Kirsher ROMCmd = 0x48,
148a88394cfSJeff Kirsher CSR11 = 0x58,
149a88394cfSJeff Kirsher SIAStatus = 0x60,
150a88394cfSJeff Kirsher CSR13 = 0x68,
151a88394cfSJeff Kirsher CSR14 = 0x70,
152a88394cfSJeff Kirsher CSR15 = 0x78,
153a88394cfSJeff Kirsher PCIPM = 0x40,
154a88394cfSJeff Kirsher
155a88394cfSJeff Kirsher /* BusMode bits */
156a88394cfSJeff Kirsher CmdReset = (1 << 0),
157a88394cfSJeff Kirsher CacheAlign16 = 0x00008000,
158a88394cfSJeff Kirsher BurstLen4 = 0x00000400,
159a88394cfSJeff Kirsher DescSkipLen = (DSL << 2),
160a88394cfSJeff Kirsher
161a88394cfSJeff Kirsher /* Rx/TxPoll bits */
162a88394cfSJeff Kirsher NormalTxPoll = (1 << 0),
163a88394cfSJeff Kirsher NormalRxPoll = (1 << 0),
164a88394cfSJeff Kirsher
165a88394cfSJeff Kirsher /* Tx/Rx descriptor status bits */
166a88394cfSJeff Kirsher DescOwn = (1 << 31),
167a88394cfSJeff Kirsher RxError = (1 << 15),
168a88394cfSJeff Kirsher RxErrLong = (1 << 7),
169a88394cfSJeff Kirsher RxErrCRC = (1 << 1),
170a88394cfSJeff Kirsher RxErrFIFO = (1 << 0),
171a88394cfSJeff Kirsher RxErrRunt = (1 << 11),
172a88394cfSJeff Kirsher RxErrFrame = (1 << 14),
173a88394cfSJeff Kirsher RingEnd = (1 << 25),
174a88394cfSJeff Kirsher FirstFrag = (1 << 29),
175a88394cfSJeff Kirsher LastFrag = (1 << 30),
176a88394cfSJeff Kirsher TxError = (1 << 15),
177a88394cfSJeff Kirsher TxFIFOUnder = (1 << 1),
178a88394cfSJeff Kirsher TxLinkFail = (1 << 2) | (1 << 10) | (1 << 11),
179a88394cfSJeff Kirsher TxMaxCol = (1 << 8),
180a88394cfSJeff Kirsher TxOWC = (1 << 9),
181a88394cfSJeff Kirsher TxJabber = (1 << 14),
182a88394cfSJeff Kirsher SetupFrame = (1 << 27),
183a88394cfSJeff Kirsher TxSwInt = (1 << 31),
184a88394cfSJeff Kirsher
185a88394cfSJeff Kirsher /* MacStatus bits */
186a88394cfSJeff Kirsher IntrOK = (1 << 16),
187a88394cfSJeff Kirsher IntrErr = (1 << 15),
188a88394cfSJeff Kirsher RxIntr = (1 << 6),
189a88394cfSJeff Kirsher RxEmpty = (1 << 7),
190a88394cfSJeff Kirsher TxIntr = (1 << 0),
191a88394cfSJeff Kirsher TxEmpty = (1 << 2),
192a88394cfSJeff Kirsher PciErr = (1 << 13),
193a88394cfSJeff Kirsher TxState = (1 << 22) | (1 << 21) | (1 << 20),
194a88394cfSJeff Kirsher RxState = (1 << 19) | (1 << 18) | (1 << 17),
195a88394cfSJeff Kirsher LinkFail = (1 << 12),
196a88394cfSJeff Kirsher LinkPass = (1 << 4),
197a88394cfSJeff Kirsher RxStopped = (1 << 8),
198a88394cfSJeff Kirsher TxStopped = (1 << 1),
199a88394cfSJeff Kirsher
200a88394cfSJeff Kirsher /* MacMode bits */
201a88394cfSJeff Kirsher TxEnable = (1 << 13),
202a88394cfSJeff Kirsher RxEnable = (1 << 1),
203a88394cfSJeff Kirsher RxTx = TxEnable | RxEnable,
204a88394cfSJeff Kirsher FullDuplex = (1 << 9),
205a88394cfSJeff Kirsher AcceptAllMulticast = (1 << 7),
206a88394cfSJeff Kirsher AcceptAllPhys = (1 << 6),
207a88394cfSJeff Kirsher BOCnt = (1 << 5),
208a88394cfSJeff Kirsher MacModeClear = (1<<12) | (1<<11) | (1<<10) | (1<<8) | (1<<3) |
209a88394cfSJeff Kirsher RxTx | BOCnt | AcceptAllPhys | AcceptAllMulticast,
210a88394cfSJeff Kirsher
211a88394cfSJeff Kirsher /* ROMCmd bits */
212a88394cfSJeff Kirsher EE_SHIFT_CLK = 0x02, /* EEPROM shift clock. */
213a88394cfSJeff Kirsher EE_CS = 0x01, /* EEPROM chip select. */
214a88394cfSJeff Kirsher EE_DATA_WRITE = 0x04, /* Data from the Tulip to EEPROM. */
215a88394cfSJeff Kirsher EE_WRITE_0 = 0x01,
216a88394cfSJeff Kirsher EE_WRITE_1 = 0x05,
217a88394cfSJeff Kirsher EE_DATA_READ = 0x08, /* Data from the EEPROM chip. */
218a88394cfSJeff Kirsher EE_ENB = (0x4800 | EE_CS),
219a88394cfSJeff Kirsher
220a88394cfSJeff Kirsher /* The EEPROM commands include the alway-set leading bit. */
221a88394cfSJeff Kirsher EE_READ_CMD = 6,
222a88394cfSJeff Kirsher
223a88394cfSJeff Kirsher /* RxMissed bits */
224a88394cfSJeff Kirsher RxMissedOver = (1 << 16),
225a88394cfSJeff Kirsher RxMissedMask = 0xffff,
226a88394cfSJeff Kirsher
227a88394cfSJeff Kirsher /* SROM-related bits */
228a88394cfSJeff Kirsher SROMC0InfoLeaf = 27,
229a88394cfSJeff Kirsher MediaBlockMask = 0x3f,
230a88394cfSJeff Kirsher MediaCustomCSRs = (1 << 6),
231a88394cfSJeff Kirsher
232a88394cfSJeff Kirsher /* PCIPM bits */
233a88394cfSJeff Kirsher PM_Sleep = (1 << 31),
234a88394cfSJeff Kirsher PM_Snooze = (1 << 30),
235a88394cfSJeff Kirsher PM_Mask = PM_Sleep | PM_Snooze,
236a88394cfSJeff Kirsher
237a88394cfSJeff Kirsher /* SIAStatus bits */
238a88394cfSJeff Kirsher NWayState = (1 << 14) | (1 << 13) | (1 << 12),
239a88394cfSJeff Kirsher NWayRestart = (1 << 12),
240a88394cfSJeff Kirsher NonselPortActive = (1 << 9),
241a88394cfSJeff Kirsher SelPortActive = (1 << 8),
242a88394cfSJeff Kirsher LinkFailStatus = (1 << 2),
243a88394cfSJeff Kirsher NetCxnErr = (1 << 1),
244a88394cfSJeff Kirsher };
245a88394cfSJeff Kirsher
246a88394cfSJeff Kirsher static const u32 de_intr_mask =
247a88394cfSJeff Kirsher IntrOK | IntrErr | RxIntr | RxEmpty | TxIntr | TxEmpty |
248a88394cfSJeff Kirsher LinkPass | LinkFail | PciErr;
249a88394cfSJeff Kirsher
250a88394cfSJeff Kirsher /*
251a88394cfSJeff Kirsher * Set the programmable burst length to 4 longwords for all:
252a88394cfSJeff Kirsher * DMA errors result without these values. Cache align 16 long.
253a88394cfSJeff Kirsher */
254a88394cfSJeff Kirsher static const u32 de_bus_mode = CacheAlign16 | BurstLen4 | DescSkipLen;
255a88394cfSJeff Kirsher
256a88394cfSJeff Kirsher struct de_srom_media_block {
257a88394cfSJeff Kirsher u8 opts;
258a88394cfSJeff Kirsher u16 csr13;
259a88394cfSJeff Kirsher u16 csr14;
260a88394cfSJeff Kirsher u16 csr15;
261a88394cfSJeff Kirsher } __packed;
262a88394cfSJeff Kirsher
263a88394cfSJeff Kirsher struct de_srom_info_leaf {
264a88394cfSJeff Kirsher u16 default_media;
265a88394cfSJeff Kirsher u8 n_blocks;
266a88394cfSJeff Kirsher u8 unused;
267a88394cfSJeff Kirsher } __packed;
268a88394cfSJeff Kirsher
269a88394cfSJeff Kirsher struct de_desc {
270a88394cfSJeff Kirsher __le32 opts1;
271a88394cfSJeff Kirsher __le32 opts2;
272a88394cfSJeff Kirsher __le32 addr1;
273a88394cfSJeff Kirsher __le32 addr2;
274a88394cfSJeff Kirsher #if DSL
275a88394cfSJeff Kirsher __le32 skip[DSL];
276a88394cfSJeff Kirsher #endif
277a88394cfSJeff Kirsher };
278a88394cfSJeff Kirsher
279a88394cfSJeff Kirsher struct media_info {
280a88394cfSJeff Kirsher u16 type; /* DE_MEDIA_xxx */
281a88394cfSJeff Kirsher u16 csr13;
282a88394cfSJeff Kirsher u16 csr14;
283a88394cfSJeff Kirsher u16 csr15;
284a88394cfSJeff Kirsher };
285a88394cfSJeff Kirsher
286a88394cfSJeff Kirsher struct ring_info {
287a88394cfSJeff Kirsher struct sk_buff *skb;
288a88394cfSJeff Kirsher dma_addr_t mapping;
289a88394cfSJeff Kirsher };
290a88394cfSJeff Kirsher
291a88394cfSJeff Kirsher struct de_private {
292a88394cfSJeff Kirsher unsigned tx_head;
293a88394cfSJeff Kirsher unsigned tx_tail;
294a88394cfSJeff Kirsher unsigned rx_tail;
295a88394cfSJeff Kirsher
296a88394cfSJeff Kirsher void __iomem *regs;
297a88394cfSJeff Kirsher struct net_device *dev;
298a88394cfSJeff Kirsher spinlock_t lock;
299a88394cfSJeff Kirsher
300a88394cfSJeff Kirsher struct de_desc *rx_ring;
301a88394cfSJeff Kirsher struct de_desc *tx_ring;
302a88394cfSJeff Kirsher struct ring_info tx_skb[DE_TX_RING_SIZE];
303a88394cfSJeff Kirsher struct ring_info rx_skb[DE_RX_RING_SIZE];
304a88394cfSJeff Kirsher unsigned rx_buf_sz;
305a88394cfSJeff Kirsher dma_addr_t ring_dma;
306a88394cfSJeff Kirsher
307a88394cfSJeff Kirsher u32 msg_enable;
308a88394cfSJeff Kirsher
309a88394cfSJeff Kirsher struct pci_dev *pdev;
310a88394cfSJeff Kirsher
311a88394cfSJeff Kirsher u16 setup_frame[DE_SETUP_FRAME_WORDS];
312a88394cfSJeff Kirsher
313a88394cfSJeff Kirsher u32 media_type;
314a88394cfSJeff Kirsher u32 media_supported;
315a88394cfSJeff Kirsher u32 media_advertise;
316a88394cfSJeff Kirsher struct media_info media[DE_MAX_MEDIA];
317a88394cfSJeff Kirsher struct timer_list media_timer;
318a88394cfSJeff Kirsher
319a88394cfSJeff Kirsher u8 *ee_data;
320a88394cfSJeff Kirsher unsigned board_idx;
321a88394cfSJeff Kirsher unsigned de21040 : 1;
322a88394cfSJeff Kirsher unsigned media_lock : 1;
323a88394cfSJeff Kirsher };
324a88394cfSJeff Kirsher
325a88394cfSJeff Kirsher
326a88394cfSJeff Kirsher static void de_set_rx_mode (struct net_device *dev);
327a88394cfSJeff Kirsher static void de_tx (struct de_private *de);
328a88394cfSJeff Kirsher static void de_clean_rings (struct de_private *de);
329a88394cfSJeff Kirsher static void de_media_interrupt (struct de_private *de, u32 status);
33041fce703SKees Cook static void de21040_media_timer (struct timer_list *t);
33141fce703SKees Cook static void de21041_media_timer (struct timer_list *t);
332a88394cfSJeff Kirsher static unsigned int de_ok_to_advertise (struct de_private *de, u32 new_media);
333a88394cfSJeff Kirsher
334a88394cfSJeff Kirsher
3359baa3c34SBenoit Taine static const struct pci_device_id de_pci_tbl[] = {
336a88394cfSJeff Kirsher { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
337a88394cfSJeff Kirsher PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
338a88394cfSJeff Kirsher { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
339a88394cfSJeff Kirsher PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
340a88394cfSJeff Kirsher { },
341a88394cfSJeff Kirsher };
342a88394cfSJeff Kirsher MODULE_DEVICE_TABLE(pci, de_pci_tbl);
343a88394cfSJeff Kirsher
344a88394cfSJeff Kirsher static const char * const media_name[DE_MAX_MEDIA] = {
345a88394cfSJeff Kirsher "10baseT auto",
346a88394cfSJeff Kirsher "BNC",
347a88394cfSJeff Kirsher "AUI",
348a88394cfSJeff Kirsher "10baseT-HD",
349a88394cfSJeff Kirsher "10baseT-FD"
350a88394cfSJeff Kirsher };
351a88394cfSJeff Kirsher
352a88394cfSJeff Kirsher /* 21040 transceiver register settings:
353a88394cfSJeff Kirsher * TP AUTO(unused), BNC(unused), AUI, TP, TP FD*/
354a88394cfSJeff Kirsher static u16 t21040_csr13[] = { 0, 0, 0x8F09, 0x8F01, 0x8F01, };
355a88394cfSJeff Kirsher static u16 t21040_csr14[] = { 0, 0, 0x0705, 0xFFFF, 0xFFFD, };
356a88394cfSJeff Kirsher static u16 t21040_csr15[] = { 0, 0, 0x0006, 0x0000, 0x0000, };
357a88394cfSJeff Kirsher
358a88394cfSJeff Kirsher /* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/
359a88394cfSJeff Kirsher static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, };
360a88394cfSJeff Kirsher static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
361a88394cfSJeff Kirsher /* If on-chip autonegotiation is broken, use half-duplex (FF3F) instead */
362a88394cfSJeff Kirsher static u16 t21041_csr14_brk[] = { 0xFF3F, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
363a88394cfSJeff Kirsher static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
364a88394cfSJeff Kirsher
365a88394cfSJeff Kirsher
366a88394cfSJeff Kirsher #define dr32(reg) ioread32(de->regs + (reg))
367a88394cfSJeff Kirsher #define dw32(reg, val) iowrite32((val), de->regs + (reg))
368a88394cfSJeff Kirsher
369a88394cfSJeff Kirsher
de_rx_err_acct(struct de_private * de,unsigned rx_tail,u32 status,u32 len)370a88394cfSJeff Kirsher static void de_rx_err_acct (struct de_private *de, unsigned rx_tail,
371a88394cfSJeff Kirsher u32 status, u32 len)
372a88394cfSJeff Kirsher {
373a88394cfSJeff Kirsher netif_dbg(de, rx_err, de->dev,
374a88394cfSJeff Kirsher "rx err, slot %d status 0x%x len %d\n",
375a88394cfSJeff Kirsher rx_tail, status, len);
376a88394cfSJeff Kirsher
377a88394cfSJeff Kirsher if ((status & 0x38000300) != 0x0300) {
378a88394cfSJeff Kirsher /* Ingore earlier buffers. */
379a88394cfSJeff Kirsher if ((status & 0xffff) != 0x7fff) {
380a88394cfSJeff Kirsher netif_warn(de, rx_err, de->dev,
381a88394cfSJeff Kirsher "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
382a88394cfSJeff Kirsher status);
383ae9eb1a7STobias Klauser de->dev->stats.rx_length_errors++;
384a88394cfSJeff Kirsher }
385a88394cfSJeff Kirsher } else if (status & RxError) {
386a88394cfSJeff Kirsher /* There was a fatal error. */
387ae9eb1a7STobias Klauser de->dev->stats.rx_errors++; /* end of a packet.*/
388ae9eb1a7STobias Klauser if (status & 0x0890) de->dev->stats.rx_length_errors++;
389ae9eb1a7STobias Klauser if (status & RxErrCRC) de->dev->stats.rx_crc_errors++;
390ae9eb1a7STobias Klauser if (status & RxErrFIFO) de->dev->stats.rx_fifo_errors++;
391a88394cfSJeff Kirsher }
392a88394cfSJeff Kirsher }
393a88394cfSJeff Kirsher
de_rx(struct de_private * de)394a88394cfSJeff Kirsher static void de_rx (struct de_private *de)
395a88394cfSJeff Kirsher {
396a88394cfSJeff Kirsher unsigned rx_tail = de->rx_tail;
397a88394cfSJeff Kirsher unsigned rx_work = DE_RX_RING_SIZE;
398a88394cfSJeff Kirsher unsigned drop = 0;
399a88394cfSJeff Kirsher int rc;
400a88394cfSJeff Kirsher
401a88394cfSJeff Kirsher while (--rx_work) {
402a88394cfSJeff Kirsher u32 status, len;
403a88394cfSJeff Kirsher dma_addr_t mapping;
404a88394cfSJeff Kirsher struct sk_buff *skb, *copy_skb;
405a88394cfSJeff Kirsher unsigned copying_skb, buflen;
406a88394cfSJeff Kirsher
407a88394cfSJeff Kirsher skb = de->rx_skb[rx_tail].skb;
408a88394cfSJeff Kirsher BUG_ON(!skb);
409a88394cfSJeff Kirsher rmb();
410a88394cfSJeff Kirsher status = le32_to_cpu(de->rx_ring[rx_tail].opts1);
411a88394cfSJeff Kirsher if (status & DescOwn)
412a88394cfSJeff Kirsher break;
413a88394cfSJeff Kirsher
41433e2b32bSMoritz Fischer /* the length is actually a 15 bit value here according
41533e2b32bSMoritz Fischer * to Table 4-1 in the DE2104x spec so mask is 0x7fff
41633e2b32bSMoritz Fischer */
41733e2b32bSMoritz Fischer len = ((status >> 16) & 0x7fff) - 4;
418a88394cfSJeff Kirsher mapping = de->rx_skb[rx_tail].mapping;
419a88394cfSJeff Kirsher
420a88394cfSJeff Kirsher if (unlikely(drop)) {
421ae9eb1a7STobias Klauser de->dev->stats.rx_dropped++;
422a88394cfSJeff Kirsher goto rx_next;
423a88394cfSJeff Kirsher }
424a88394cfSJeff Kirsher
425a88394cfSJeff Kirsher if (unlikely((status & 0x38008300) != 0x0300)) {
426a88394cfSJeff Kirsher de_rx_err_acct(de, rx_tail, status, len);
427a88394cfSJeff Kirsher goto rx_next;
428a88394cfSJeff Kirsher }
429a88394cfSJeff Kirsher
430a88394cfSJeff Kirsher copying_skb = (len <= rx_copybreak);
431a88394cfSJeff Kirsher
432a88394cfSJeff Kirsher netif_dbg(de, rx_status, de->dev,
433a88394cfSJeff Kirsher "rx slot %d status 0x%x len %d copying? %d\n",
434a88394cfSJeff Kirsher rx_tail, status, len, copying_skb);
435a88394cfSJeff Kirsher
436a88394cfSJeff Kirsher buflen = copying_skb ? (len + RX_OFFSET) : de->rx_buf_sz;
43721a4e469SPradeep A Dalvi copy_skb = netdev_alloc_skb(de->dev, buflen);
438a88394cfSJeff Kirsher if (unlikely(!copy_skb)) {
439ae9eb1a7STobias Klauser de->dev->stats.rx_dropped++;
440a88394cfSJeff Kirsher drop = 1;
441a88394cfSJeff Kirsher rx_work = 100;
442a88394cfSJeff Kirsher goto rx_next;
443a88394cfSJeff Kirsher }
444a88394cfSJeff Kirsher
445a88394cfSJeff Kirsher if (!copying_skb) {
4467a1fe380SChristophe JAILLET dma_unmap_single(&de->pdev->dev, mapping, buflen,
4477a1fe380SChristophe JAILLET DMA_FROM_DEVICE);
448a88394cfSJeff Kirsher skb_put(skb, len);
449a88394cfSJeff Kirsher
450a88394cfSJeff Kirsher mapping =
451a88394cfSJeff Kirsher de->rx_skb[rx_tail].mapping =
4527a1fe380SChristophe JAILLET dma_map_single(&de->pdev->dev, copy_skb->data,
4537a1fe380SChristophe JAILLET buflen, DMA_FROM_DEVICE);
454a88394cfSJeff Kirsher de->rx_skb[rx_tail].skb = copy_skb;
455a88394cfSJeff Kirsher } else {
4567a1fe380SChristophe JAILLET dma_sync_single_for_cpu(&de->pdev->dev, mapping, len,
4577a1fe380SChristophe JAILLET DMA_FROM_DEVICE);
458a88394cfSJeff Kirsher skb_reserve(copy_skb, RX_OFFSET);
459a88394cfSJeff Kirsher skb_copy_from_linear_data(skb, skb_put(copy_skb, len),
460a88394cfSJeff Kirsher len);
4617a1fe380SChristophe JAILLET dma_sync_single_for_device(&de->pdev->dev, mapping,
4627a1fe380SChristophe JAILLET len, DMA_FROM_DEVICE);
463a88394cfSJeff Kirsher
464a88394cfSJeff Kirsher /* We'll reuse the original ring buffer. */
465a88394cfSJeff Kirsher skb = copy_skb;
466a88394cfSJeff Kirsher }
467a88394cfSJeff Kirsher
468a88394cfSJeff Kirsher skb->protocol = eth_type_trans (skb, de->dev);
469a88394cfSJeff Kirsher
470ae9eb1a7STobias Klauser de->dev->stats.rx_packets++;
471ae9eb1a7STobias Klauser de->dev->stats.rx_bytes += skb->len;
472a88394cfSJeff Kirsher rc = netif_rx (skb);
473a88394cfSJeff Kirsher if (rc == NET_RX_DROP)
474a88394cfSJeff Kirsher drop = 1;
475a88394cfSJeff Kirsher
476a88394cfSJeff Kirsher rx_next:
477a88394cfSJeff Kirsher if (rx_tail == (DE_RX_RING_SIZE - 1))
478a88394cfSJeff Kirsher de->rx_ring[rx_tail].opts2 =
479a88394cfSJeff Kirsher cpu_to_le32(RingEnd | de->rx_buf_sz);
480a88394cfSJeff Kirsher else
481a88394cfSJeff Kirsher de->rx_ring[rx_tail].opts2 = cpu_to_le32(de->rx_buf_sz);
482a88394cfSJeff Kirsher de->rx_ring[rx_tail].addr1 = cpu_to_le32(mapping);
483a88394cfSJeff Kirsher wmb();
484a88394cfSJeff Kirsher de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn);
485a88394cfSJeff Kirsher rx_tail = NEXT_RX(rx_tail);
486a88394cfSJeff Kirsher }
487a88394cfSJeff Kirsher
488a88394cfSJeff Kirsher if (!rx_work)
489a88394cfSJeff Kirsher netdev_warn(de->dev, "rx work limit reached\n");
490a88394cfSJeff Kirsher
491a88394cfSJeff Kirsher de->rx_tail = rx_tail;
492a88394cfSJeff Kirsher }
493a88394cfSJeff Kirsher
de_interrupt(int irq,void * dev_instance)494a88394cfSJeff Kirsher static irqreturn_t de_interrupt (int irq, void *dev_instance)
495a88394cfSJeff Kirsher {
496a88394cfSJeff Kirsher struct net_device *dev = dev_instance;
497a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
498a88394cfSJeff Kirsher u32 status;
499a88394cfSJeff Kirsher
500a88394cfSJeff Kirsher status = dr32(MacStatus);
501a88394cfSJeff Kirsher if ((!(status & (IntrOK|IntrErr))) || (status == 0xFFFF))
502a88394cfSJeff Kirsher return IRQ_NONE;
503a88394cfSJeff Kirsher
504a88394cfSJeff Kirsher netif_dbg(de, intr, dev, "intr, status %08x mode %08x desc %u/%u/%u\n",
505a88394cfSJeff Kirsher status, dr32(MacMode),
506a88394cfSJeff Kirsher de->rx_tail, de->tx_head, de->tx_tail);
507a88394cfSJeff Kirsher
508a88394cfSJeff Kirsher dw32(MacStatus, status);
509a88394cfSJeff Kirsher
510a88394cfSJeff Kirsher if (status & (RxIntr | RxEmpty)) {
511a88394cfSJeff Kirsher de_rx(de);
512a88394cfSJeff Kirsher if (status & RxEmpty)
513a88394cfSJeff Kirsher dw32(RxPoll, NormalRxPoll);
514a88394cfSJeff Kirsher }
515a88394cfSJeff Kirsher
516a88394cfSJeff Kirsher spin_lock(&de->lock);
517a88394cfSJeff Kirsher
518a88394cfSJeff Kirsher if (status & (TxIntr | TxEmpty))
519a88394cfSJeff Kirsher de_tx(de);
520a88394cfSJeff Kirsher
521a88394cfSJeff Kirsher if (status & (LinkPass | LinkFail))
522a88394cfSJeff Kirsher de_media_interrupt(de, status);
523a88394cfSJeff Kirsher
524a88394cfSJeff Kirsher spin_unlock(&de->lock);
525a88394cfSJeff Kirsher
526a88394cfSJeff Kirsher if (status & PciErr) {
527a88394cfSJeff Kirsher u16 pci_status;
528a88394cfSJeff Kirsher
529a88394cfSJeff Kirsher pci_read_config_word(de->pdev, PCI_STATUS, &pci_status);
530a88394cfSJeff Kirsher pci_write_config_word(de->pdev, PCI_STATUS, pci_status);
531a88394cfSJeff Kirsher netdev_err(de->dev,
532a88394cfSJeff Kirsher "PCI bus error, status=%08x, PCI status=%04x\n",
533a88394cfSJeff Kirsher status, pci_status);
534a88394cfSJeff Kirsher }
535a88394cfSJeff Kirsher
536a88394cfSJeff Kirsher return IRQ_HANDLED;
537a88394cfSJeff Kirsher }
538a88394cfSJeff Kirsher
de_tx(struct de_private * de)539a88394cfSJeff Kirsher static void de_tx (struct de_private *de)
540a88394cfSJeff Kirsher {
541a88394cfSJeff Kirsher unsigned tx_head = de->tx_head;
542a88394cfSJeff Kirsher unsigned tx_tail = de->tx_tail;
543a88394cfSJeff Kirsher
544a88394cfSJeff Kirsher while (tx_tail != tx_head) {
545a88394cfSJeff Kirsher struct sk_buff *skb;
546a88394cfSJeff Kirsher u32 status;
547a88394cfSJeff Kirsher
548a88394cfSJeff Kirsher rmb();
549a88394cfSJeff Kirsher status = le32_to_cpu(de->tx_ring[tx_tail].opts1);
550a88394cfSJeff Kirsher if (status & DescOwn)
551a88394cfSJeff Kirsher break;
552a88394cfSJeff Kirsher
553a88394cfSJeff Kirsher skb = de->tx_skb[tx_tail].skb;
554a88394cfSJeff Kirsher BUG_ON(!skb);
555a88394cfSJeff Kirsher if (unlikely(skb == DE_DUMMY_SKB))
556a88394cfSJeff Kirsher goto next;
557a88394cfSJeff Kirsher
558a88394cfSJeff Kirsher if (unlikely(skb == DE_SETUP_SKB)) {
5597a1fe380SChristophe JAILLET dma_unmap_single(&de->pdev->dev,
5607a1fe380SChristophe JAILLET de->tx_skb[tx_tail].mapping,
5617a1fe380SChristophe JAILLET sizeof(de->setup_frame),
5627a1fe380SChristophe JAILLET DMA_TO_DEVICE);
563a88394cfSJeff Kirsher goto next;
564a88394cfSJeff Kirsher }
565a88394cfSJeff Kirsher
5667a1fe380SChristophe JAILLET dma_unmap_single(&de->pdev->dev, de->tx_skb[tx_tail].mapping,
5677a1fe380SChristophe JAILLET skb->len, DMA_TO_DEVICE);
568a88394cfSJeff Kirsher
569a88394cfSJeff Kirsher if (status & LastFrag) {
570a88394cfSJeff Kirsher if (status & TxError) {
571a88394cfSJeff Kirsher netif_dbg(de, tx_err, de->dev,
572a88394cfSJeff Kirsher "tx err, status 0x%x\n",
573a88394cfSJeff Kirsher status);
574ae9eb1a7STobias Klauser de->dev->stats.tx_errors++;
575a88394cfSJeff Kirsher if (status & TxOWC)
576ae9eb1a7STobias Klauser de->dev->stats.tx_window_errors++;
577a88394cfSJeff Kirsher if (status & TxMaxCol)
578ae9eb1a7STobias Klauser de->dev->stats.tx_aborted_errors++;
579a88394cfSJeff Kirsher if (status & TxLinkFail)
580ae9eb1a7STobias Klauser de->dev->stats.tx_carrier_errors++;
581a88394cfSJeff Kirsher if (status & TxFIFOUnder)
582ae9eb1a7STobias Klauser de->dev->stats.tx_fifo_errors++;
583a88394cfSJeff Kirsher } else {
584ae9eb1a7STobias Klauser de->dev->stats.tx_packets++;
585ae9eb1a7STobias Klauser de->dev->stats.tx_bytes += skb->len;
586a88394cfSJeff Kirsher netif_dbg(de, tx_done, de->dev,
587a88394cfSJeff Kirsher "tx done, slot %d\n", tx_tail);
588a88394cfSJeff Kirsher }
58962d1a31cSYang Wei dev_consume_skb_irq(skb);
590a88394cfSJeff Kirsher }
591a88394cfSJeff Kirsher
592a88394cfSJeff Kirsher next:
593a88394cfSJeff Kirsher de->tx_skb[tx_tail].skb = NULL;
594a88394cfSJeff Kirsher
595a88394cfSJeff Kirsher tx_tail = NEXT_TX(tx_tail);
596a88394cfSJeff Kirsher }
597a88394cfSJeff Kirsher
598a88394cfSJeff Kirsher de->tx_tail = tx_tail;
599a88394cfSJeff Kirsher
600a88394cfSJeff Kirsher if (netif_queue_stopped(de->dev) && (TX_BUFFS_AVAIL(de) > (DE_TX_RING_SIZE / 4)))
601a88394cfSJeff Kirsher netif_wake_queue(de->dev);
602a88394cfSJeff Kirsher }
603a88394cfSJeff Kirsher
de_start_xmit(struct sk_buff * skb,struct net_device * dev)604a88394cfSJeff Kirsher static netdev_tx_t de_start_xmit (struct sk_buff *skb,
605a88394cfSJeff Kirsher struct net_device *dev)
606a88394cfSJeff Kirsher {
607a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
608a88394cfSJeff Kirsher unsigned int entry, tx_free;
609a88394cfSJeff Kirsher u32 mapping, len, flags = FirstFrag | LastFrag;
610a88394cfSJeff Kirsher struct de_desc *txd;
611a88394cfSJeff Kirsher
612a88394cfSJeff Kirsher spin_lock_irq(&de->lock);
613a88394cfSJeff Kirsher
614a88394cfSJeff Kirsher tx_free = TX_BUFFS_AVAIL(de);
615a88394cfSJeff Kirsher if (tx_free == 0) {
616a88394cfSJeff Kirsher netif_stop_queue(dev);
617a88394cfSJeff Kirsher spin_unlock_irq(&de->lock);
618a88394cfSJeff Kirsher return NETDEV_TX_BUSY;
619a88394cfSJeff Kirsher }
620a88394cfSJeff Kirsher tx_free--;
621a88394cfSJeff Kirsher
622a88394cfSJeff Kirsher entry = de->tx_head;
623a88394cfSJeff Kirsher
624a88394cfSJeff Kirsher txd = &de->tx_ring[entry];
625a88394cfSJeff Kirsher
626a88394cfSJeff Kirsher len = skb->len;
6277a1fe380SChristophe JAILLET mapping = dma_map_single(&de->pdev->dev, skb->data, len,
6287a1fe380SChristophe JAILLET DMA_TO_DEVICE);
629a88394cfSJeff Kirsher if (entry == (DE_TX_RING_SIZE - 1))
630a88394cfSJeff Kirsher flags |= RingEnd;
631a88394cfSJeff Kirsher if (!tx_free || (tx_free == (DE_TX_RING_SIZE / 2)))
632a88394cfSJeff Kirsher flags |= TxSwInt;
633a88394cfSJeff Kirsher flags |= len;
634a88394cfSJeff Kirsher txd->opts2 = cpu_to_le32(flags);
635a88394cfSJeff Kirsher txd->addr1 = cpu_to_le32(mapping);
636a88394cfSJeff Kirsher
637a88394cfSJeff Kirsher de->tx_skb[entry].skb = skb;
638a88394cfSJeff Kirsher de->tx_skb[entry].mapping = mapping;
639a88394cfSJeff Kirsher wmb();
640a88394cfSJeff Kirsher
641a88394cfSJeff Kirsher txd->opts1 = cpu_to_le32(DescOwn);
642a88394cfSJeff Kirsher wmb();
643a88394cfSJeff Kirsher
644a88394cfSJeff Kirsher de->tx_head = NEXT_TX(entry);
645a88394cfSJeff Kirsher netif_dbg(de, tx_queued, dev, "tx queued, slot %d, skblen %d\n",
646a88394cfSJeff Kirsher entry, skb->len);
647a88394cfSJeff Kirsher
648a88394cfSJeff Kirsher if (tx_free == 0)
649a88394cfSJeff Kirsher netif_stop_queue(dev);
650a88394cfSJeff Kirsher
651a88394cfSJeff Kirsher spin_unlock_irq(&de->lock);
652a88394cfSJeff Kirsher
653a88394cfSJeff Kirsher /* Trigger an immediate transmit demand. */
654a88394cfSJeff Kirsher dw32(TxPoll, NormalTxPoll);
655a88394cfSJeff Kirsher
656a88394cfSJeff Kirsher return NETDEV_TX_OK;
657a88394cfSJeff Kirsher }
658a88394cfSJeff Kirsher
659a88394cfSJeff Kirsher /* Set or clear the multicast filter for this adaptor.
660a88394cfSJeff Kirsher Note that we only use exclusion around actually queueing the
661a88394cfSJeff Kirsher new frame, not around filling de->setup_frame. This is non-deterministic
662a88394cfSJeff Kirsher when re-entered but still correct. */
663a88394cfSJeff Kirsher
build_setup_frame_hash(u16 * setup_frm,struct net_device * dev)664a88394cfSJeff Kirsher static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev)
665a88394cfSJeff Kirsher {
666a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
667a88394cfSJeff Kirsher u16 hash_table[32];
668a88394cfSJeff Kirsher struct netdev_hw_addr *ha;
669ca879317SJakub Kicinski const u16 *eaddrs;
670a88394cfSJeff Kirsher int i;
671a88394cfSJeff Kirsher
672a88394cfSJeff Kirsher memset(hash_table, 0, sizeof(hash_table));
673459a1308STakuya Yoshikawa __set_bit_le(255, hash_table); /* Broadcast entry */
674a88394cfSJeff Kirsher /* This should work on big-endian machines as well. */
675a88394cfSJeff Kirsher netdev_for_each_mc_addr(ha, dev) {
676a88394cfSJeff Kirsher int index = ether_crc_le(ETH_ALEN, ha->addr) & 0x1ff;
677a88394cfSJeff Kirsher
678459a1308STakuya Yoshikawa __set_bit_le(index, hash_table);
679a88394cfSJeff Kirsher }
680a88394cfSJeff Kirsher
681a88394cfSJeff Kirsher for (i = 0; i < 32; i++) {
682a88394cfSJeff Kirsher *setup_frm++ = hash_table[i];
683a88394cfSJeff Kirsher *setup_frm++ = hash_table[i];
684a88394cfSJeff Kirsher }
685a88394cfSJeff Kirsher setup_frm = &de->setup_frame[13*6];
686a88394cfSJeff Kirsher
687a88394cfSJeff Kirsher /* Fill the final entry with our physical address. */
688ca879317SJakub Kicinski eaddrs = (const u16 *)dev->dev_addr;
689a88394cfSJeff Kirsher *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
690a88394cfSJeff Kirsher *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
691a88394cfSJeff Kirsher *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
692a88394cfSJeff Kirsher }
693a88394cfSJeff Kirsher
build_setup_frame_perfect(u16 * setup_frm,struct net_device * dev)694a88394cfSJeff Kirsher static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev)
695a88394cfSJeff Kirsher {
696a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
697a88394cfSJeff Kirsher struct netdev_hw_addr *ha;
698ca879317SJakub Kicinski const u16 *eaddrs;
699a88394cfSJeff Kirsher
700a88394cfSJeff Kirsher /* We have <= 14 addresses so we can use the wonderful
701a88394cfSJeff Kirsher 16 address perfect filtering of the Tulip. */
702a88394cfSJeff Kirsher netdev_for_each_mc_addr(ha, dev) {
703a88394cfSJeff Kirsher eaddrs = (u16 *) ha->addr;
704a88394cfSJeff Kirsher *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
705a88394cfSJeff Kirsher *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
706a88394cfSJeff Kirsher *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
707a88394cfSJeff Kirsher }
708a88394cfSJeff Kirsher /* Fill the unused entries with the broadcast address. */
709a88394cfSJeff Kirsher memset(setup_frm, 0xff, (15 - netdev_mc_count(dev)) * 12);
710a88394cfSJeff Kirsher setup_frm = &de->setup_frame[15*6];
711a88394cfSJeff Kirsher
712a88394cfSJeff Kirsher /* Fill the final entry with our physical address. */
713ca879317SJakub Kicinski eaddrs = (const u16 *)dev->dev_addr;
714a88394cfSJeff Kirsher *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
715a88394cfSJeff Kirsher *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
716a88394cfSJeff Kirsher *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
717a88394cfSJeff Kirsher }
718a88394cfSJeff Kirsher
719a88394cfSJeff Kirsher
__de_set_rx_mode(struct net_device * dev)720a88394cfSJeff Kirsher static void __de_set_rx_mode (struct net_device *dev)
721a88394cfSJeff Kirsher {
722a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
723a88394cfSJeff Kirsher u32 macmode;
724a88394cfSJeff Kirsher unsigned int entry;
725a88394cfSJeff Kirsher u32 mapping;
726a88394cfSJeff Kirsher struct de_desc *txd;
727a88394cfSJeff Kirsher struct de_desc *dummy_txd = NULL;
728a88394cfSJeff Kirsher
729a88394cfSJeff Kirsher macmode = dr32(MacMode) & ~(AcceptAllMulticast | AcceptAllPhys);
730a88394cfSJeff Kirsher
731a88394cfSJeff Kirsher if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
732a88394cfSJeff Kirsher macmode |= AcceptAllMulticast | AcceptAllPhys;
733a88394cfSJeff Kirsher goto out;
734a88394cfSJeff Kirsher }
735a88394cfSJeff Kirsher
736a88394cfSJeff Kirsher if ((netdev_mc_count(dev) > 1000) || (dev->flags & IFF_ALLMULTI)) {
737a88394cfSJeff Kirsher /* Too many to filter well -- accept all multicasts. */
738a88394cfSJeff Kirsher macmode |= AcceptAllMulticast;
739a88394cfSJeff Kirsher goto out;
740a88394cfSJeff Kirsher }
741a88394cfSJeff Kirsher
742a88394cfSJeff Kirsher /* Note that only the low-address shortword of setup_frame is valid!
743a88394cfSJeff Kirsher The values are doubled for big-endian architectures. */
744a88394cfSJeff Kirsher if (netdev_mc_count(dev) > 14) /* Must use a multicast hash table. */
745a88394cfSJeff Kirsher build_setup_frame_hash (de->setup_frame, dev);
746a88394cfSJeff Kirsher else
747a88394cfSJeff Kirsher build_setup_frame_perfect (de->setup_frame, dev);
748a88394cfSJeff Kirsher
749a88394cfSJeff Kirsher /*
750a88394cfSJeff Kirsher * Now add this frame to the Tx list.
751a88394cfSJeff Kirsher */
752a88394cfSJeff Kirsher
753a88394cfSJeff Kirsher entry = de->tx_head;
754a88394cfSJeff Kirsher
755a88394cfSJeff Kirsher /* Avoid a chip errata by prefixing a dummy entry. */
756a88394cfSJeff Kirsher if (entry != 0) {
757a88394cfSJeff Kirsher de->tx_skb[entry].skb = DE_DUMMY_SKB;
758a88394cfSJeff Kirsher
759a88394cfSJeff Kirsher dummy_txd = &de->tx_ring[entry];
760a88394cfSJeff Kirsher dummy_txd->opts2 = (entry == (DE_TX_RING_SIZE - 1)) ?
761a88394cfSJeff Kirsher cpu_to_le32(RingEnd) : 0;
762a88394cfSJeff Kirsher dummy_txd->addr1 = 0;
763a88394cfSJeff Kirsher
764a88394cfSJeff Kirsher /* Must set DescOwned later to avoid race with chip */
765a88394cfSJeff Kirsher
766a88394cfSJeff Kirsher entry = NEXT_TX(entry);
767a88394cfSJeff Kirsher }
768a88394cfSJeff Kirsher
769a88394cfSJeff Kirsher de->tx_skb[entry].skb = DE_SETUP_SKB;
770a88394cfSJeff Kirsher de->tx_skb[entry].mapping = mapping =
7717a1fe380SChristophe JAILLET dma_map_single(&de->pdev->dev, de->setup_frame,
7727a1fe380SChristophe JAILLET sizeof(de->setup_frame), DMA_TO_DEVICE);
773a88394cfSJeff Kirsher
774a88394cfSJeff Kirsher /* Put the setup frame on the Tx list. */
775a88394cfSJeff Kirsher txd = &de->tx_ring[entry];
776a88394cfSJeff Kirsher if (entry == (DE_TX_RING_SIZE - 1))
777a88394cfSJeff Kirsher txd->opts2 = cpu_to_le32(SetupFrame | RingEnd | sizeof (de->setup_frame));
778a88394cfSJeff Kirsher else
779a88394cfSJeff Kirsher txd->opts2 = cpu_to_le32(SetupFrame | sizeof (de->setup_frame));
780a88394cfSJeff Kirsher txd->addr1 = cpu_to_le32(mapping);
781a88394cfSJeff Kirsher wmb();
782a88394cfSJeff Kirsher
783a88394cfSJeff Kirsher txd->opts1 = cpu_to_le32(DescOwn);
784a88394cfSJeff Kirsher wmb();
785a88394cfSJeff Kirsher
786a88394cfSJeff Kirsher if (dummy_txd) {
787a88394cfSJeff Kirsher dummy_txd->opts1 = cpu_to_le32(DescOwn);
788a88394cfSJeff Kirsher wmb();
789a88394cfSJeff Kirsher }
790a88394cfSJeff Kirsher
791a88394cfSJeff Kirsher de->tx_head = NEXT_TX(entry);
792a88394cfSJeff Kirsher
793a88394cfSJeff Kirsher if (TX_BUFFS_AVAIL(de) == 0)
794a88394cfSJeff Kirsher netif_stop_queue(dev);
795a88394cfSJeff Kirsher
796a88394cfSJeff Kirsher /* Trigger an immediate transmit demand. */
797a88394cfSJeff Kirsher dw32(TxPoll, NormalTxPoll);
798a88394cfSJeff Kirsher
799a88394cfSJeff Kirsher out:
800a88394cfSJeff Kirsher if (macmode != dr32(MacMode))
801a88394cfSJeff Kirsher dw32(MacMode, macmode);
802a88394cfSJeff Kirsher }
803a88394cfSJeff Kirsher
de_set_rx_mode(struct net_device * dev)804a88394cfSJeff Kirsher static void de_set_rx_mode (struct net_device *dev)
805a88394cfSJeff Kirsher {
806a88394cfSJeff Kirsher unsigned long flags;
807a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
808a88394cfSJeff Kirsher
809a88394cfSJeff Kirsher spin_lock_irqsave (&de->lock, flags);
810a88394cfSJeff Kirsher __de_set_rx_mode(dev);
811a88394cfSJeff Kirsher spin_unlock_irqrestore (&de->lock, flags);
812a88394cfSJeff Kirsher }
813a88394cfSJeff Kirsher
de_rx_missed(struct de_private * de,u32 rx_missed)814a88394cfSJeff Kirsher static inline void de_rx_missed(struct de_private *de, u32 rx_missed)
815a88394cfSJeff Kirsher {
816a88394cfSJeff Kirsher if (unlikely(rx_missed & RxMissedOver))
817ae9eb1a7STobias Klauser de->dev->stats.rx_missed_errors += RxMissedMask;
818a88394cfSJeff Kirsher else
819ae9eb1a7STobias Klauser de->dev->stats.rx_missed_errors += (rx_missed & RxMissedMask);
820a88394cfSJeff Kirsher }
821a88394cfSJeff Kirsher
__de_get_stats(struct de_private * de)822a88394cfSJeff Kirsher static void __de_get_stats(struct de_private *de)
823a88394cfSJeff Kirsher {
824a88394cfSJeff Kirsher u32 tmp = dr32(RxMissed); /* self-clearing */
825a88394cfSJeff Kirsher
826a88394cfSJeff Kirsher de_rx_missed(de, tmp);
827a88394cfSJeff Kirsher }
828a88394cfSJeff Kirsher
de_get_stats(struct net_device * dev)829a88394cfSJeff Kirsher static struct net_device_stats *de_get_stats(struct net_device *dev)
830a88394cfSJeff Kirsher {
831a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
832a88394cfSJeff Kirsher
833a88394cfSJeff Kirsher /* The chip only need report frame silently dropped. */
834a88394cfSJeff Kirsher spin_lock_irq(&de->lock);
835a88394cfSJeff Kirsher if (netif_running(dev) && netif_device_present(dev))
836a88394cfSJeff Kirsher __de_get_stats(de);
837a88394cfSJeff Kirsher spin_unlock_irq(&de->lock);
838a88394cfSJeff Kirsher
839ae9eb1a7STobias Klauser return &dev->stats;
840a88394cfSJeff Kirsher }
841a88394cfSJeff Kirsher
de_is_running(struct de_private * de)842a88394cfSJeff Kirsher static inline int de_is_running (struct de_private *de)
843a88394cfSJeff Kirsher {
844a88394cfSJeff Kirsher return (dr32(MacStatus) & (RxState | TxState)) ? 1 : 0;
845a88394cfSJeff Kirsher }
846a88394cfSJeff Kirsher
de_stop_rxtx(struct de_private * de)847a88394cfSJeff Kirsher static void de_stop_rxtx (struct de_private *de)
848a88394cfSJeff Kirsher {
849a88394cfSJeff Kirsher u32 macmode;
850a88394cfSJeff Kirsher unsigned int i = 1300/100;
851a88394cfSJeff Kirsher
852a88394cfSJeff Kirsher macmode = dr32(MacMode);
853a88394cfSJeff Kirsher if (macmode & RxTx) {
854a88394cfSJeff Kirsher dw32(MacMode, macmode & ~RxTx);
855a88394cfSJeff Kirsher dr32(MacMode);
856a88394cfSJeff Kirsher }
857a88394cfSJeff Kirsher
858a88394cfSJeff Kirsher /* wait until in-flight frame completes.
859a88394cfSJeff Kirsher * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin)
860a88394cfSJeff Kirsher * Typically expect this loop to end in < 50 us on 100BT.
861a88394cfSJeff Kirsher */
862a88394cfSJeff Kirsher while (--i) {
863a88394cfSJeff Kirsher if (!de_is_running(de))
864a88394cfSJeff Kirsher return;
865a88394cfSJeff Kirsher udelay(100);
866a88394cfSJeff Kirsher }
867a88394cfSJeff Kirsher
868a88394cfSJeff Kirsher netdev_warn(de->dev, "timeout expired, stopping DMA\n");
869a88394cfSJeff Kirsher }
870a88394cfSJeff Kirsher
de_start_rxtx(struct de_private * de)871a88394cfSJeff Kirsher static inline void de_start_rxtx (struct de_private *de)
872a88394cfSJeff Kirsher {
873a88394cfSJeff Kirsher u32 macmode;
874a88394cfSJeff Kirsher
875a88394cfSJeff Kirsher macmode = dr32(MacMode);
876a88394cfSJeff Kirsher if ((macmode & RxTx) != RxTx) {
877a88394cfSJeff Kirsher dw32(MacMode, macmode | RxTx);
878a88394cfSJeff Kirsher dr32(MacMode);
879a88394cfSJeff Kirsher }
880a88394cfSJeff Kirsher }
881a88394cfSJeff Kirsher
de_stop_hw(struct de_private * de)882a88394cfSJeff Kirsher static void de_stop_hw (struct de_private *de)
883a88394cfSJeff Kirsher {
884a88394cfSJeff Kirsher
885a88394cfSJeff Kirsher udelay(5);
886a88394cfSJeff Kirsher dw32(IntrMask, 0);
887a88394cfSJeff Kirsher
888a88394cfSJeff Kirsher de_stop_rxtx(de);
889a88394cfSJeff Kirsher
890a88394cfSJeff Kirsher dw32(MacStatus, dr32(MacStatus));
891a88394cfSJeff Kirsher
892a88394cfSJeff Kirsher udelay(10);
893a88394cfSJeff Kirsher
894a88394cfSJeff Kirsher de->rx_tail = 0;
895a88394cfSJeff Kirsher de->tx_head = de->tx_tail = 0;
896a88394cfSJeff Kirsher }
897a88394cfSJeff Kirsher
de_link_up(struct de_private * de)898a88394cfSJeff Kirsher static void de_link_up(struct de_private *de)
899a88394cfSJeff Kirsher {
900a88394cfSJeff Kirsher if (!netif_carrier_ok(de->dev)) {
901a88394cfSJeff Kirsher netif_carrier_on(de->dev);
902a88394cfSJeff Kirsher netif_info(de, link, de->dev, "link up, media %s\n",
903a88394cfSJeff Kirsher media_name[de->media_type]);
904a88394cfSJeff Kirsher }
905a88394cfSJeff Kirsher }
906a88394cfSJeff Kirsher
de_link_down(struct de_private * de)907a88394cfSJeff Kirsher static void de_link_down(struct de_private *de)
908a88394cfSJeff Kirsher {
909a88394cfSJeff Kirsher if (netif_carrier_ok(de->dev)) {
910a88394cfSJeff Kirsher netif_carrier_off(de->dev);
911a88394cfSJeff Kirsher netif_info(de, link, de->dev, "link down\n");
912a88394cfSJeff Kirsher }
913a88394cfSJeff Kirsher }
914a88394cfSJeff Kirsher
de_set_media(struct de_private * de)915a88394cfSJeff Kirsher static void de_set_media (struct de_private *de)
916a88394cfSJeff Kirsher {
917a88394cfSJeff Kirsher unsigned media = de->media_type;
918a88394cfSJeff Kirsher u32 macmode = dr32(MacMode);
919a88394cfSJeff Kirsher
920a88394cfSJeff Kirsher if (de_is_running(de))
921a88394cfSJeff Kirsher netdev_warn(de->dev, "chip is running while changing media!\n");
922a88394cfSJeff Kirsher
923a88394cfSJeff Kirsher if (de->de21040)
924a88394cfSJeff Kirsher dw32(CSR11, FULL_DUPLEX_MAGIC);
925a88394cfSJeff Kirsher dw32(CSR13, 0); /* Reset phy */
926a88394cfSJeff Kirsher dw32(CSR14, de->media[media].csr14);
927a88394cfSJeff Kirsher dw32(CSR15, de->media[media].csr15);
928a88394cfSJeff Kirsher dw32(CSR13, de->media[media].csr13);
929a88394cfSJeff Kirsher
930a88394cfSJeff Kirsher /* must delay 10ms before writing to other registers,
931a88394cfSJeff Kirsher * especially CSR6
932a88394cfSJeff Kirsher */
933a88394cfSJeff Kirsher mdelay(10);
934a88394cfSJeff Kirsher
935a88394cfSJeff Kirsher if (media == DE_MEDIA_TP_FD)
936a88394cfSJeff Kirsher macmode |= FullDuplex;
937a88394cfSJeff Kirsher else
938a88394cfSJeff Kirsher macmode &= ~FullDuplex;
939a88394cfSJeff Kirsher
940a88394cfSJeff Kirsher netif_info(de, link, de->dev, "set link %s\n", media_name[media]);
941a88394cfSJeff Kirsher netif_info(de, hw, de->dev, "mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n",
942a88394cfSJeff Kirsher dr32(MacMode), dr32(SIAStatus),
943a88394cfSJeff Kirsher dr32(CSR13), dr32(CSR14), dr32(CSR15));
944a88394cfSJeff Kirsher netif_info(de, hw, de->dev, "set mode 0x%x, set sia 0x%x,0x%x,0x%x\n",
945a88394cfSJeff Kirsher macmode, de->media[media].csr13,
946a88394cfSJeff Kirsher de->media[media].csr14, de->media[media].csr15);
947a88394cfSJeff Kirsher if (macmode != dr32(MacMode))
948a88394cfSJeff Kirsher dw32(MacMode, macmode);
949a88394cfSJeff Kirsher }
950a88394cfSJeff Kirsher
de_next_media(struct de_private * de,const u32 * media,unsigned int n_media)951a88394cfSJeff Kirsher static void de_next_media (struct de_private *de, const u32 *media,
952a88394cfSJeff Kirsher unsigned int n_media)
953a88394cfSJeff Kirsher {
954a88394cfSJeff Kirsher unsigned int i;
955a88394cfSJeff Kirsher
956a88394cfSJeff Kirsher for (i = 0; i < n_media; i++) {
957a88394cfSJeff Kirsher if (de_ok_to_advertise(de, media[i])) {
958a88394cfSJeff Kirsher de->media_type = media[i];
959a88394cfSJeff Kirsher return;
960a88394cfSJeff Kirsher }
961a88394cfSJeff Kirsher }
962a88394cfSJeff Kirsher }
963a88394cfSJeff Kirsher
de21040_media_timer(struct timer_list * t)96441fce703SKees Cook static void de21040_media_timer (struct timer_list *t)
965a88394cfSJeff Kirsher {
96641fce703SKees Cook struct de_private *de = from_timer(de, t, media_timer);
967a88394cfSJeff Kirsher struct net_device *dev = de->dev;
968a88394cfSJeff Kirsher u32 status = dr32(SIAStatus);
969a88394cfSJeff Kirsher unsigned int carrier;
970a88394cfSJeff Kirsher unsigned long flags;
971a88394cfSJeff Kirsher
972a88394cfSJeff Kirsher carrier = (status & NetCxnErr) ? 0 : 1;
973a88394cfSJeff Kirsher
974a88394cfSJeff Kirsher if (carrier) {
975a88394cfSJeff Kirsher if (de->media_type != DE_MEDIA_AUI && (status & LinkFailStatus))
976a88394cfSJeff Kirsher goto no_link_yet;
977a88394cfSJeff Kirsher
978a88394cfSJeff Kirsher de->media_timer.expires = jiffies + DE_TIMER_LINK;
979a88394cfSJeff Kirsher add_timer(&de->media_timer);
980a88394cfSJeff Kirsher if (!netif_carrier_ok(dev))
981a88394cfSJeff Kirsher de_link_up(de);
982a88394cfSJeff Kirsher else
983a88394cfSJeff Kirsher netif_info(de, timer, dev, "%s link ok, status %x\n",
984a88394cfSJeff Kirsher media_name[de->media_type], status);
985a88394cfSJeff Kirsher return;
986a88394cfSJeff Kirsher }
987a88394cfSJeff Kirsher
988a88394cfSJeff Kirsher de_link_down(de);
989a88394cfSJeff Kirsher
990a88394cfSJeff Kirsher if (de->media_lock)
991a88394cfSJeff Kirsher return;
992a88394cfSJeff Kirsher
993a88394cfSJeff Kirsher if (de->media_type == DE_MEDIA_AUI) {
994a88394cfSJeff Kirsher static const u32 next_state = DE_MEDIA_TP;
995a88394cfSJeff Kirsher de_next_media(de, &next_state, 1);
996a88394cfSJeff Kirsher } else {
997a88394cfSJeff Kirsher static const u32 next_state = DE_MEDIA_AUI;
998a88394cfSJeff Kirsher de_next_media(de, &next_state, 1);
999a88394cfSJeff Kirsher }
1000a88394cfSJeff Kirsher
1001a88394cfSJeff Kirsher spin_lock_irqsave(&de->lock, flags);
1002a88394cfSJeff Kirsher de_stop_rxtx(de);
1003a88394cfSJeff Kirsher spin_unlock_irqrestore(&de->lock, flags);
1004a88394cfSJeff Kirsher de_set_media(de);
1005a88394cfSJeff Kirsher de_start_rxtx(de);
1006a88394cfSJeff Kirsher
1007a88394cfSJeff Kirsher no_link_yet:
1008a88394cfSJeff Kirsher de->media_timer.expires = jiffies + DE_TIMER_NO_LINK;
1009a88394cfSJeff Kirsher add_timer(&de->media_timer);
1010a88394cfSJeff Kirsher
1011a88394cfSJeff Kirsher netif_info(de, timer, dev, "no link, trying media %s, status %x\n",
1012a88394cfSJeff Kirsher media_name[de->media_type], status);
1013a88394cfSJeff Kirsher }
1014a88394cfSJeff Kirsher
de_ok_to_advertise(struct de_private * de,u32 new_media)1015a88394cfSJeff Kirsher static unsigned int de_ok_to_advertise (struct de_private *de, u32 new_media)
1016a88394cfSJeff Kirsher {
1017a88394cfSJeff Kirsher switch (new_media) {
1018a88394cfSJeff Kirsher case DE_MEDIA_TP_AUTO:
1019a88394cfSJeff Kirsher if (!(de->media_advertise & ADVERTISED_Autoneg))
1020a88394cfSJeff Kirsher return 0;
1021a88394cfSJeff Kirsher if (!(de->media_advertise & (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full)))
1022a88394cfSJeff Kirsher return 0;
1023a88394cfSJeff Kirsher break;
1024a88394cfSJeff Kirsher case DE_MEDIA_BNC:
1025a88394cfSJeff Kirsher if (!(de->media_advertise & ADVERTISED_BNC))
1026a88394cfSJeff Kirsher return 0;
1027a88394cfSJeff Kirsher break;
1028a88394cfSJeff Kirsher case DE_MEDIA_AUI:
1029a88394cfSJeff Kirsher if (!(de->media_advertise & ADVERTISED_AUI))
1030a88394cfSJeff Kirsher return 0;
1031a88394cfSJeff Kirsher break;
1032a88394cfSJeff Kirsher case DE_MEDIA_TP:
1033a88394cfSJeff Kirsher if (!(de->media_advertise & ADVERTISED_10baseT_Half))
1034a88394cfSJeff Kirsher return 0;
1035a88394cfSJeff Kirsher break;
1036a88394cfSJeff Kirsher case DE_MEDIA_TP_FD:
1037a88394cfSJeff Kirsher if (!(de->media_advertise & ADVERTISED_10baseT_Full))
1038a88394cfSJeff Kirsher return 0;
1039a88394cfSJeff Kirsher break;
1040a88394cfSJeff Kirsher }
1041a88394cfSJeff Kirsher
1042a88394cfSJeff Kirsher return 1;
1043a88394cfSJeff Kirsher }
1044a88394cfSJeff Kirsher
de21041_media_timer(struct timer_list * t)104541fce703SKees Cook static void de21041_media_timer (struct timer_list *t)
1046a88394cfSJeff Kirsher {
104741fce703SKees Cook struct de_private *de = from_timer(de, t, media_timer);
1048a88394cfSJeff Kirsher struct net_device *dev = de->dev;
1049a88394cfSJeff Kirsher u32 status = dr32(SIAStatus);
1050a88394cfSJeff Kirsher unsigned int carrier;
1051a88394cfSJeff Kirsher unsigned long flags;
1052a88394cfSJeff Kirsher
1053a88394cfSJeff Kirsher /* clear port active bits */
1054a88394cfSJeff Kirsher dw32(SIAStatus, NonselPortActive | SelPortActive);
1055a88394cfSJeff Kirsher
1056a88394cfSJeff Kirsher carrier = (status & NetCxnErr) ? 0 : 1;
1057a88394cfSJeff Kirsher
1058a88394cfSJeff Kirsher if (carrier) {
1059a88394cfSJeff Kirsher if ((de->media_type == DE_MEDIA_TP_AUTO ||
1060a88394cfSJeff Kirsher de->media_type == DE_MEDIA_TP ||
1061a88394cfSJeff Kirsher de->media_type == DE_MEDIA_TP_FD) &&
1062a88394cfSJeff Kirsher (status & LinkFailStatus))
1063a88394cfSJeff Kirsher goto no_link_yet;
1064a88394cfSJeff Kirsher
1065a88394cfSJeff Kirsher de->media_timer.expires = jiffies + DE_TIMER_LINK;
1066a88394cfSJeff Kirsher add_timer(&de->media_timer);
1067a88394cfSJeff Kirsher if (!netif_carrier_ok(dev))
1068a88394cfSJeff Kirsher de_link_up(de);
1069a88394cfSJeff Kirsher else
1070a88394cfSJeff Kirsher netif_info(de, timer, dev,
1071a88394cfSJeff Kirsher "%s link ok, mode %x status %x\n",
1072a88394cfSJeff Kirsher media_name[de->media_type],
1073a88394cfSJeff Kirsher dr32(MacMode), status);
1074a88394cfSJeff Kirsher return;
1075a88394cfSJeff Kirsher }
1076a88394cfSJeff Kirsher
1077a88394cfSJeff Kirsher de_link_down(de);
1078a88394cfSJeff Kirsher
1079a88394cfSJeff Kirsher /* if media type locked, don't switch media */
1080a88394cfSJeff Kirsher if (de->media_lock)
1081a88394cfSJeff Kirsher goto set_media;
1082a88394cfSJeff Kirsher
1083a88394cfSJeff Kirsher /* if activity detected, use that as hint for new media type */
1084a88394cfSJeff Kirsher if (status & NonselPortActive) {
1085a88394cfSJeff Kirsher unsigned int have_media = 1;
1086a88394cfSJeff Kirsher
1087a88394cfSJeff Kirsher /* if AUI/BNC selected, then activity is on TP port */
1088a88394cfSJeff Kirsher if (de->media_type == DE_MEDIA_AUI ||
1089a88394cfSJeff Kirsher de->media_type == DE_MEDIA_BNC) {
1090a88394cfSJeff Kirsher if (de_ok_to_advertise(de, DE_MEDIA_TP_AUTO))
1091a88394cfSJeff Kirsher de->media_type = DE_MEDIA_TP_AUTO;
1092a88394cfSJeff Kirsher else
1093a88394cfSJeff Kirsher have_media = 0;
1094a88394cfSJeff Kirsher }
1095a88394cfSJeff Kirsher
1096a88394cfSJeff Kirsher /* TP selected. If there is only TP and BNC, then it's BNC */
1097a88394cfSJeff Kirsher else if (((de->media_supported & DE_AUI_BNC) == SUPPORTED_BNC) &&
1098a88394cfSJeff Kirsher de_ok_to_advertise(de, DE_MEDIA_BNC))
1099a88394cfSJeff Kirsher de->media_type = DE_MEDIA_BNC;
1100a88394cfSJeff Kirsher
1101a88394cfSJeff Kirsher /* TP selected. If there is only TP and AUI, then it's AUI */
1102a88394cfSJeff Kirsher else if (((de->media_supported & DE_AUI_BNC) == SUPPORTED_AUI) &&
1103a88394cfSJeff Kirsher de_ok_to_advertise(de, DE_MEDIA_AUI))
1104a88394cfSJeff Kirsher de->media_type = DE_MEDIA_AUI;
1105a88394cfSJeff Kirsher
1106a88394cfSJeff Kirsher /* otherwise, ignore the hint */
1107a88394cfSJeff Kirsher else
1108a88394cfSJeff Kirsher have_media = 0;
1109a88394cfSJeff Kirsher
1110a88394cfSJeff Kirsher if (have_media)
1111a88394cfSJeff Kirsher goto set_media;
1112a88394cfSJeff Kirsher }
1113a88394cfSJeff Kirsher
1114a88394cfSJeff Kirsher /*
1115a88394cfSJeff Kirsher * Absent or ambiguous activity hint, move to next advertised
1116a88394cfSJeff Kirsher * media state. If de->media_type is left unchanged, this
1117a88394cfSJeff Kirsher * simply resets the PHY and reloads the current media settings.
1118a88394cfSJeff Kirsher */
1119a88394cfSJeff Kirsher if (de->media_type == DE_MEDIA_AUI) {
1120a88394cfSJeff Kirsher static const u32 next_states[] = {
1121a88394cfSJeff Kirsher DE_MEDIA_BNC, DE_MEDIA_TP_AUTO
1122a88394cfSJeff Kirsher };
1123a88394cfSJeff Kirsher de_next_media(de, next_states, ARRAY_SIZE(next_states));
1124a88394cfSJeff Kirsher } else if (de->media_type == DE_MEDIA_BNC) {
1125a88394cfSJeff Kirsher static const u32 next_states[] = {
1126a88394cfSJeff Kirsher DE_MEDIA_TP_AUTO, DE_MEDIA_AUI
1127a88394cfSJeff Kirsher };
1128a88394cfSJeff Kirsher de_next_media(de, next_states, ARRAY_SIZE(next_states));
1129a88394cfSJeff Kirsher } else {
1130a88394cfSJeff Kirsher static const u32 next_states[] = {
1131a88394cfSJeff Kirsher DE_MEDIA_AUI, DE_MEDIA_BNC, DE_MEDIA_TP_AUTO
1132a88394cfSJeff Kirsher };
1133a88394cfSJeff Kirsher de_next_media(de, next_states, ARRAY_SIZE(next_states));
1134a88394cfSJeff Kirsher }
1135a88394cfSJeff Kirsher
1136a88394cfSJeff Kirsher set_media:
1137a88394cfSJeff Kirsher spin_lock_irqsave(&de->lock, flags);
1138a88394cfSJeff Kirsher de_stop_rxtx(de);
1139a88394cfSJeff Kirsher spin_unlock_irqrestore(&de->lock, flags);
1140a88394cfSJeff Kirsher de_set_media(de);
1141a88394cfSJeff Kirsher de_start_rxtx(de);
1142a88394cfSJeff Kirsher
1143a88394cfSJeff Kirsher no_link_yet:
1144a88394cfSJeff Kirsher de->media_timer.expires = jiffies + DE_TIMER_NO_LINK;
1145a88394cfSJeff Kirsher add_timer(&de->media_timer);
1146a88394cfSJeff Kirsher
1147a88394cfSJeff Kirsher netif_info(de, timer, dev, "no link, trying media %s, status %x\n",
1148a88394cfSJeff Kirsher media_name[de->media_type], status);
1149a88394cfSJeff Kirsher }
1150a88394cfSJeff Kirsher
de_media_interrupt(struct de_private * de,u32 status)1151a88394cfSJeff Kirsher static void de_media_interrupt (struct de_private *de, u32 status)
1152a88394cfSJeff Kirsher {
1153a88394cfSJeff Kirsher if (status & LinkPass) {
1154a88394cfSJeff Kirsher /* Ignore if current media is AUI or BNC and we can't use TP */
1155a88394cfSJeff Kirsher if ((de->media_type == DE_MEDIA_AUI ||
1156a88394cfSJeff Kirsher de->media_type == DE_MEDIA_BNC) &&
1157a88394cfSJeff Kirsher (de->media_lock ||
1158a88394cfSJeff Kirsher !de_ok_to_advertise(de, DE_MEDIA_TP_AUTO)))
1159a88394cfSJeff Kirsher return;
1160a88394cfSJeff Kirsher /* If current media is not TP, change it to TP */
1161a88394cfSJeff Kirsher if ((de->media_type == DE_MEDIA_AUI ||
1162a88394cfSJeff Kirsher de->media_type == DE_MEDIA_BNC)) {
1163a88394cfSJeff Kirsher de->media_type = DE_MEDIA_TP_AUTO;
1164a88394cfSJeff Kirsher de_stop_rxtx(de);
1165a88394cfSJeff Kirsher de_set_media(de);
1166a88394cfSJeff Kirsher de_start_rxtx(de);
1167a88394cfSJeff Kirsher }
1168a88394cfSJeff Kirsher de_link_up(de);
1169a88394cfSJeff Kirsher mod_timer(&de->media_timer, jiffies + DE_TIMER_LINK);
1170a88394cfSJeff Kirsher return;
1171a88394cfSJeff Kirsher }
1172a88394cfSJeff Kirsher
1173a88394cfSJeff Kirsher BUG_ON(!(status & LinkFail));
1174a88394cfSJeff Kirsher /* Mark the link as down only if current media is TP */
1175a88394cfSJeff Kirsher if (netif_carrier_ok(de->dev) && de->media_type != DE_MEDIA_AUI &&
1176a88394cfSJeff Kirsher de->media_type != DE_MEDIA_BNC) {
1177a88394cfSJeff Kirsher de_link_down(de);
1178a88394cfSJeff Kirsher mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK);
1179a88394cfSJeff Kirsher }
1180a88394cfSJeff Kirsher }
1181a88394cfSJeff Kirsher
de_reset_mac(struct de_private * de)1182a88394cfSJeff Kirsher static int de_reset_mac (struct de_private *de)
1183a88394cfSJeff Kirsher {
1184a88394cfSJeff Kirsher u32 status, tmp;
1185a88394cfSJeff Kirsher
1186a88394cfSJeff Kirsher /*
1187a88394cfSJeff Kirsher * Reset MAC. de4x5.c and tulip.c examined for "advice"
1188a88394cfSJeff Kirsher * in this area.
1189a88394cfSJeff Kirsher */
1190a88394cfSJeff Kirsher
1191a88394cfSJeff Kirsher if (dr32(BusMode) == 0xffffffff)
1192a88394cfSJeff Kirsher return -EBUSY;
1193a88394cfSJeff Kirsher
1194a88394cfSJeff Kirsher /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
1195a88394cfSJeff Kirsher dw32 (BusMode, CmdReset);
1196a88394cfSJeff Kirsher mdelay (1);
1197a88394cfSJeff Kirsher
1198a88394cfSJeff Kirsher dw32 (BusMode, de_bus_mode);
1199a88394cfSJeff Kirsher mdelay (1);
1200a88394cfSJeff Kirsher
1201a88394cfSJeff Kirsher for (tmp = 0; tmp < 5; tmp++) {
1202a88394cfSJeff Kirsher dr32 (BusMode);
1203a88394cfSJeff Kirsher mdelay (1);
1204a88394cfSJeff Kirsher }
1205a88394cfSJeff Kirsher
1206a88394cfSJeff Kirsher mdelay (1);
1207a88394cfSJeff Kirsher
1208a88394cfSJeff Kirsher status = dr32(MacStatus);
1209a88394cfSJeff Kirsher if (status & (RxState | TxState))
1210a88394cfSJeff Kirsher return -EBUSY;
1211a88394cfSJeff Kirsher if (status == 0xffffffff)
1212a88394cfSJeff Kirsher return -ENODEV;
1213a88394cfSJeff Kirsher return 0;
1214a88394cfSJeff Kirsher }
1215a88394cfSJeff Kirsher
de_adapter_wake(struct de_private * de)1216a88394cfSJeff Kirsher static void de_adapter_wake (struct de_private *de)
1217a88394cfSJeff Kirsher {
1218a88394cfSJeff Kirsher u32 pmctl;
1219a88394cfSJeff Kirsher
1220a88394cfSJeff Kirsher if (de->de21040)
1221a88394cfSJeff Kirsher return;
1222a88394cfSJeff Kirsher
1223a88394cfSJeff Kirsher pci_read_config_dword(de->pdev, PCIPM, &pmctl);
1224a88394cfSJeff Kirsher if (pmctl & PM_Mask) {
1225a88394cfSJeff Kirsher pmctl &= ~PM_Mask;
1226a88394cfSJeff Kirsher pci_write_config_dword(de->pdev, PCIPM, pmctl);
1227a88394cfSJeff Kirsher
1228a88394cfSJeff Kirsher /* de4x5.c delays, so we do too */
1229a88394cfSJeff Kirsher msleep(10);
1230a88394cfSJeff Kirsher }
1231a88394cfSJeff Kirsher }
1232a88394cfSJeff Kirsher
de_adapter_sleep(struct de_private * de)1233a88394cfSJeff Kirsher static void de_adapter_sleep (struct de_private *de)
1234a88394cfSJeff Kirsher {
1235a88394cfSJeff Kirsher u32 pmctl;
1236a88394cfSJeff Kirsher
1237a88394cfSJeff Kirsher if (de->de21040)
1238a88394cfSJeff Kirsher return;
1239a88394cfSJeff Kirsher
1240a88394cfSJeff Kirsher dw32(CSR13, 0); /* Reset phy */
1241a88394cfSJeff Kirsher pci_read_config_dword(de->pdev, PCIPM, &pmctl);
1242a88394cfSJeff Kirsher pmctl |= PM_Sleep;
1243a88394cfSJeff Kirsher pci_write_config_dword(de->pdev, PCIPM, pmctl);
1244a88394cfSJeff Kirsher }
1245a88394cfSJeff Kirsher
de_init_hw(struct de_private * de)1246a88394cfSJeff Kirsher static int de_init_hw (struct de_private *de)
1247a88394cfSJeff Kirsher {
1248a88394cfSJeff Kirsher struct net_device *dev = de->dev;
1249a88394cfSJeff Kirsher u32 macmode;
1250a88394cfSJeff Kirsher int rc;
1251a88394cfSJeff Kirsher
1252a88394cfSJeff Kirsher de_adapter_wake(de);
1253a88394cfSJeff Kirsher
1254a88394cfSJeff Kirsher macmode = dr32(MacMode) & ~MacModeClear;
1255a88394cfSJeff Kirsher
1256a88394cfSJeff Kirsher rc = de_reset_mac(de);
1257a88394cfSJeff Kirsher if (rc)
1258a88394cfSJeff Kirsher return rc;
1259a88394cfSJeff Kirsher
1260a88394cfSJeff Kirsher de_set_media(de); /* reset phy */
1261a88394cfSJeff Kirsher
1262a88394cfSJeff Kirsher dw32(RxRingAddr, de->ring_dma);
1263a88394cfSJeff Kirsher dw32(TxRingAddr, de->ring_dma + (sizeof(struct de_desc) * DE_RX_RING_SIZE));
1264a88394cfSJeff Kirsher
1265a88394cfSJeff Kirsher dw32(MacMode, RxTx | macmode);
1266a88394cfSJeff Kirsher
1267a88394cfSJeff Kirsher dr32(RxMissed); /* self-clearing */
1268a88394cfSJeff Kirsher
1269a88394cfSJeff Kirsher dw32(IntrMask, de_intr_mask);
1270a88394cfSJeff Kirsher
1271a88394cfSJeff Kirsher de_set_rx_mode(dev);
1272a88394cfSJeff Kirsher
1273a88394cfSJeff Kirsher return 0;
1274a88394cfSJeff Kirsher }
1275a88394cfSJeff Kirsher
de_refill_rx(struct de_private * de)1276a88394cfSJeff Kirsher static int de_refill_rx (struct de_private *de)
1277a88394cfSJeff Kirsher {
1278a88394cfSJeff Kirsher unsigned i;
1279a88394cfSJeff Kirsher
1280a88394cfSJeff Kirsher for (i = 0; i < DE_RX_RING_SIZE; i++) {
1281a88394cfSJeff Kirsher struct sk_buff *skb;
1282a88394cfSJeff Kirsher
128321a4e469SPradeep A Dalvi skb = netdev_alloc_skb(de->dev, de->rx_buf_sz);
1284a88394cfSJeff Kirsher if (!skb)
1285a88394cfSJeff Kirsher goto err_out;
1286a88394cfSJeff Kirsher
12877a1fe380SChristophe JAILLET de->rx_skb[i].mapping = dma_map_single(&de->pdev->dev,
12887a1fe380SChristophe JAILLET skb->data,
12897a1fe380SChristophe JAILLET de->rx_buf_sz,
12907a1fe380SChristophe JAILLET DMA_FROM_DEVICE);
1291a88394cfSJeff Kirsher de->rx_skb[i].skb = skb;
1292a88394cfSJeff Kirsher
1293a88394cfSJeff Kirsher de->rx_ring[i].opts1 = cpu_to_le32(DescOwn);
1294a88394cfSJeff Kirsher if (i == (DE_RX_RING_SIZE - 1))
1295a88394cfSJeff Kirsher de->rx_ring[i].opts2 =
1296a88394cfSJeff Kirsher cpu_to_le32(RingEnd | de->rx_buf_sz);
1297a88394cfSJeff Kirsher else
1298a88394cfSJeff Kirsher de->rx_ring[i].opts2 = cpu_to_le32(de->rx_buf_sz);
1299a88394cfSJeff Kirsher de->rx_ring[i].addr1 = cpu_to_le32(de->rx_skb[i].mapping);
1300a88394cfSJeff Kirsher de->rx_ring[i].addr2 = 0;
1301a88394cfSJeff Kirsher }
1302a88394cfSJeff Kirsher
1303a88394cfSJeff Kirsher return 0;
1304a88394cfSJeff Kirsher
1305a88394cfSJeff Kirsher err_out:
1306a88394cfSJeff Kirsher de_clean_rings(de);
1307a88394cfSJeff Kirsher return -ENOMEM;
1308a88394cfSJeff Kirsher }
1309a88394cfSJeff Kirsher
de_init_rings(struct de_private * de)1310a88394cfSJeff Kirsher static int de_init_rings (struct de_private *de)
1311a88394cfSJeff Kirsher {
1312a88394cfSJeff Kirsher memset(de->tx_ring, 0, sizeof(struct de_desc) * DE_TX_RING_SIZE);
1313a88394cfSJeff Kirsher de->tx_ring[DE_TX_RING_SIZE - 1].opts2 = cpu_to_le32(RingEnd);
1314a88394cfSJeff Kirsher
1315a88394cfSJeff Kirsher de->rx_tail = 0;
1316a88394cfSJeff Kirsher de->tx_head = de->tx_tail = 0;
1317a88394cfSJeff Kirsher
1318a88394cfSJeff Kirsher return de_refill_rx (de);
1319a88394cfSJeff Kirsher }
1320a88394cfSJeff Kirsher
de_alloc_rings(struct de_private * de)1321a88394cfSJeff Kirsher static int de_alloc_rings (struct de_private *de)
1322a88394cfSJeff Kirsher {
13237a1fe380SChristophe JAILLET de->rx_ring = dma_alloc_coherent(&de->pdev->dev, DE_RING_BYTES,
13247a1fe380SChristophe JAILLET &de->ring_dma, GFP_KERNEL);
1325a88394cfSJeff Kirsher if (!de->rx_ring)
1326a88394cfSJeff Kirsher return -ENOMEM;
1327a88394cfSJeff Kirsher de->tx_ring = &de->rx_ring[DE_RX_RING_SIZE];
1328a88394cfSJeff Kirsher return de_init_rings(de);
1329a88394cfSJeff Kirsher }
1330a88394cfSJeff Kirsher
de_clean_rings(struct de_private * de)1331a88394cfSJeff Kirsher static void de_clean_rings (struct de_private *de)
1332a88394cfSJeff Kirsher {
1333a88394cfSJeff Kirsher unsigned i;
1334a88394cfSJeff Kirsher
1335a88394cfSJeff Kirsher memset(de->rx_ring, 0, sizeof(struct de_desc) * DE_RX_RING_SIZE);
1336a88394cfSJeff Kirsher de->rx_ring[DE_RX_RING_SIZE - 1].opts2 = cpu_to_le32(RingEnd);
1337a88394cfSJeff Kirsher wmb();
1338a88394cfSJeff Kirsher memset(de->tx_ring, 0, sizeof(struct de_desc) * DE_TX_RING_SIZE);
1339a88394cfSJeff Kirsher de->tx_ring[DE_TX_RING_SIZE - 1].opts2 = cpu_to_le32(RingEnd);
1340a88394cfSJeff Kirsher wmb();
1341a88394cfSJeff Kirsher
1342a88394cfSJeff Kirsher for (i = 0; i < DE_RX_RING_SIZE; i++) {
1343a88394cfSJeff Kirsher if (de->rx_skb[i].skb) {
13447a1fe380SChristophe JAILLET dma_unmap_single(&de->pdev->dev,
13457a1fe380SChristophe JAILLET de->rx_skb[i].mapping, de->rx_buf_sz,
13467a1fe380SChristophe JAILLET DMA_FROM_DEVICE);
1347a88394cfSJeff Kirsher dev_kfree_skb(de->rx_skb[i].skb);
1348a88394cfSJeff Kirsher }
1349a88394cfSJeff Kirsher }
1350a88394cfSJeff Kirsher
1351a88394cfSJeff Kirsher for (i = 0; i < DE_TX_RING_SIZE; i++) {
1352a88394cfSJeff Kirsher struct sk_buff *skb = de->tx_skb[i].skb;
1353a88394cfSJeff Kirsher if ((skb) && (skb != DE_DUMMY_SKB)) {
1354a88394cfSJeff Kirsher if (skb != DE_SETUP_SKB) {
1355ae9eb1a7STobias Klauser de->dev->stats.tx_dropped++;
13567a1fe380SChristophe JAILLET dma_unmap_single(&de->pdev->dev,
1357a88394cfSJeff Kirsher de->tx_skb[i].mapping,
13587a1fe380SChristophe JAILLET skb->len, DMA_TO_DEVICE);
1359a88394cfSJeff Kirsher dev_kfree_skb(skb);
1360a88394cfSJeff Kirsher } else {
13617a1fe380SChristophe JAILLET dma_unmap_single(&de->pdev->dev,
1362a88394cfSJeff Kirsher de->tx_skb[i].mapping,
1363a88394cfSJeff Kirsher sizeof(de->setup_frame),
13647a1fe380SChristophe JAILLET DMA_TO_DEVICE);
1365a88394cfSJeff Kirsher }
1366a88394cfSJeff Kirsher }
1367a88394cfSJeff Kirsher }
1368a88394cfSJeff Kirsher
1369a88394cfSJeff Kirsher memset(&de->rx_skb, 0, sizeof(struct ring_info) * DE_RX_RING_SIZE);
1370a88394cfSJeff Kirsher memset(&de->tx_skb, 0, sizeof(struct ring_info) * DE_TX_RING_SIZE);
1371a88394cfSJeff Kirsher }
1372a88394cfSJeff Kirsher
de_free_rings(struct de_private * de)1373a88394cfSJeff Kirsher static void de_free_rings (struct de_private *de)
1374a88394cfSJeff Kirsher {
1375a88394cfSJeff Kirsher de_clean_rings(de);
13767a1fe380SChristophe JAILLET dma_free_coherent(&de->pdev->dev, DE_RING_BYTES, de->rx_ring,
13777a1fe380SChristophe JAILLET de->ring_dma);
1378a88394cfSJeff Kirsher de->rx_ring = NULL;
1379a88394cfSJeff Kirsher de->tx_ring = NULL;
1380a88394cfSJeff Kirsher }
1381a88394cfSJeff Kirsher
de_open(struct net_device * dev)1382a88394cfSJeff Kirsher static int de_open (struct net_device *dev)
1383a88394cfSJeff Kirsher {
1384a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1385308f2888SFrancois Romieu const int irq = de->pdev->irq;
1386a88394cfSJeff Kirsher int rc;
1387a88394cfSJeff Kirsher
1388a88394cfSJeff Kirsher netif_dbg(de, ifup, dev, "enabling interface\n");
1389a88394cfSJeff Kirsher
1390a88394cfSJeff Kirsher de->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
1391a88394cfSJeff Kirsher
1392a88394cfSJeff Kirsher rc = de_alloc_rings(de);
1393a88394cfSJeff Kirsher if (rc) {
1394a88394cfSJeff Kirsher netdev_err(dev, "ring allocation failure, err=%d\n", rc);
1395a88394cfSJeff Kirsher return rc;
1396a88394cfSJeff Kirsher }
1397a88394cfSJeff Kirsher
1398a88394cfSJeff Kirsher dw32(IntrMask, 0);
1399a88394cfSJeff Kirsher
1400308f2888SFrancois Romieu rc = request_irq(irq, de_interrupt, IRQF_SHARED, dev->name, dev);
1401a88394cfSJeff Kirsher if (rc) {
1402308f2888SFrancois Romieu netdev_err(dev, "IRQ %d request failure, err=%d\n", irq, rc);
1403a88394cfSJeff Kirsher goto err_out_free;
1404a88394cfSJeff Kirsher }
1405a88394cfSJeff Kirsher
1406a88394cfSJeff Kirsher rc = de_init_hw(de);
1407a88394cfSJeff Kirsher if (rc) {
1408a88394cfSJeff Kirsher netdev_err(dev, "h/w init failure, err=%d\n", rc);
1409a88394cfSJeff Kirsher goto err_out_free_irq;
1410a88394cfSJeff Kirsher }
1411a88394cfSJeff Kirsher
1412a88394cfSJeff Kirsher netif_start_queue(dev);
1413a88394cfSJeff Kirsher mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK);
1414a88394cfSJeff Kirsher
1415a88394cfSJeff Kirsher return 0;
1416a88394cfSJeff Kirsher
1417a88394cfSJeff Kirsher err_out_free_irq:
1418308f2888SFrancois Romieu free_irq(irq, dev);
1419a88394cfSJeff Kirsher err_out_free:
1420a88394cfSJeff Kirsher de_free_rings(de);
1421a88394cfSJeff Kirsher return rc;
1422a88394cfSJeff Kirsher }
1423a88394cfSJeff Kirsher
de_close(struct net_device * dev)1424a88394cfSJeff Kirsher static int de_close (struct net_device *dev)
1425a88394cfSJeff Kirsher {
1426a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1427a88394cfSJeff Kirsher unsigned long flags;
1428a88394cfSJeff Kirsher
1429a88394cfSJeff Kirsher netif_dbg(de, ifdown, dev, "disabling interface\n");
1430a88394cfSJeff Kirsher
1431a88394cfSJeff Kirsher del_timer_sync(&de->media_timer);
1432a88394cfSJeff Kirsher
1433a88394cfSJeff Kirsher spin_lock_irqsave(&de->lock, flags);
1434a88394cfSJeff Kirsher de_stop_hw(de);
1435a88394cfSJeff Kirsher netif_stop_queue(dev);
1436a88394cfSJeff Kirsher netif_carrier_off(dev);
1437a88394cfSJeff Kirsher spin_unlock_irqrestore(&de->lock, flags);
1438a88394cfSJeff Kirsher
1439308f2888SFrancois Romieu free_irq(de->pdev->irq, dev);
1440a88394cfSJeff Kirsher
1441a88394cfSJeff Kirsher de_free_rings(de);
1442a88394cfSJeff Kirsher de_adapter_sleep(de);
1443a88394cfSJeff Kirsher return 0;
1444a88394cfSJeff Kirsher }
1445a88394cfSJeff Kirsher
de_tx_timeout(struct net_device * dev,unsigned int txqueue)14460290bd29SMichael S. Tsirkin static void de_tx_timeout (struct net_device *dev, unsigned int txqueue)
1447a88394cfSJeff Kirsher {
1448a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1449308f2888SFrancois Romieu const int irq = de->pdev->irq;
1450a88394cfSJeff Kirsher
1451a88394cfSJeff Kirsher netdev_dbg(dev, "NIC status %08x mode %08x sia %08x desc %u/%u/%u\n",
1452a88394cfSJeff Kirsher dr32(MacStatus), dr32(MacMode), dr32(SIAStatus),
1453a88394cfSJeff Kirsher de->rx_tail, de->tx_head, de->tx_tail);
1454a88394cfSJeff Kirsher
1455a88394cfSJeff Kirsher del_timer_sync(&de->media_timer);
1456a88394cfSJeff Kirsher
1457308f2888SFrancois Romieu disable_irq(irq);
1458a88394cfSJeff Kirsher spin_lock_irq(&de->lock);
1459a88394cfSJeff Kirsher
1460a88394cfSJeff Kirsher de_stop_hw(de);
1461a88394cfSJeff Kirsher netif_stop_queue(dev);
1462a88394cfSJeff Kirsher netif_carrier_off(dev);
1463a88394cfSJeff Kirsher
1464a88394cfSJeff Kirsher spin_unlock_irq(&de->lock);
1465308f2888SFrancois Romieu enable_irq(irq);
1466a88394cfSJeff Kirsher
1467a88394cfSJeff Kirsher /* Update the error counts. */
1468a88394cfSJeff Kirsher __de_get_stats(de);
1469a88394cfSJeff Kirsher
1470308f2888SFrancois Romieu synchronize_irq(irq);
1471a88394cfSJeff Kirsher de_clean_rings(de);
1472a88394cfSJeff Kirsher
1473a88394cfSJeff Kirsher de_init_rings(de);
1474a88394cfSJeff Kirsher
1475a88394cfSJeff Kirsher de_init_hw(de);
1476a88394cfSJeff Kirsher
1477a88394cfSJeff Kirsher netif_wake_queue(dev);
1478a88394cfSJeff Kirsher }
1479a88394cfSJeff Kirsher
__de_get_regs(struct de_private * de,u8 * buf)1480a88394cfSJeff Kirsher static void __de_get_regs(struct de_private *de, u8 *buf)
1481a88394cfSJeff Kirsher {
1482a88394cfSJeff Kirsher int i;
1483a88394cfSJeff Kirsher u32 *rbuf = (u32 *)buf;
1484a88394cfSJeff Kirsher
1485a88394cfSJeff Kirsher /* read all CSRs */
1486a88394cfSJeff Kirsher for (i = 0; i < DE_NUM_REGS; i++)
1487a88394cfSJeff Kirsher rbuf[i] = dr32(i * 8);
1488a88394cfSJeff Kirsher
1489a88394cfSJeff Kirsher /* handle self-clearing RxMissed counter, CSR8 */
1490a88394cfSJeff Kirsher de_rx_missed(de, rbuf[8]);
1491a88394cfSJeff Kirsher }
1492a88394cfSJeff Kirsher
__de_get_link_ksettings(struct de_private * de,struct ethtool_link_ksettings * cmd)1493c7c6b871Syuval.shaia@oracle.com static void __de_get_link_ksettings(struct de_private *de,
149441a65f70SPhilippe Reynes struct ethtool_link_ksettings *cmd)
1495a88394cfSJeff Kirsher {
149641a65f70SPhilippe Reynes ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
149741a65f70SPhilippe Reynes de->media_supported);
149841a65f70SPhilippe Reynes cmd->base.phy_address = 0;
149941a65f70SPhilippe Reynes ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
150041a65f70SPhilippe Reynes de->media_advertise);
1501a88394cfSJeff Kirsher
1502a88394cfSJeff Kirsher switch (de->media_type) {
1503a88394cfSJeff Kirsher case DE_MEDIA_AUI:
150441a65f70SPhilippe Reynes cmd->base.port = PORT_AUI;
1505a88394cfSJeff Kirsher break;
1506a88394cfSJeff Kirsher case DE_MEDIA_BNC:
150741a65f70SPhilippe Reynes cmd->base.port = PORT_BNC;
1508a88394cfSJeff Kirsher break;
1509a88394cfSJeff Kirsher default:
151041a65f70SPhilippe Reynes cmd->base.port = PORT_TP;
1511a88394cfSJeff Kirsher break;
1512a88394cfSJeff Kirsher }
1513a88394cfSJeff Kirsher
151441a65f70SPhilippe Reynes cmd->base.speed = 10;
1515a88394cfSJeff Kirsher
1516a88394cfSJeff Kirsher if (dr32(MacMode) & FullDuplex)
151741a65f70SPhilippe Reynes cmd->base.duplex = DUPLEX_FULL;
1518a88394cfSJeff Kirsher else
151941a65f70SPhilippe Reynes cmd->base.duplex = DUPLEX_HALF;
1520a88394cfSJeff Kirsher
1521a88394cfSJeff Kirsher if (de->media_lock)
152241a65f70SPhilippe Reynes cmd->base.autoneg = AUTONEG_DISABLE;
1523a88394cfSJeff Kirsher else
152441a65f70SPhilippe Reynes cmd->base.autoneg = AUTONEG_ENABLE;
1525a88394cfSJeff Kirsher
1526a88394cfSJeff Kirsher /* ignore maxtxpkt, maxrxpkt for now */
1527a88394cfSJeff Kirsher }
1528a88394cfSJeff Kirsher
__de_set_link_ksettings(struct de_private * de,const struct ethtool_link_ksettings * cmd)152941a65f70SPhilippe Reynes static int __de_set_link_ksettings(struct de_private *de,
153041a65f70SPhilippe Reynes const struct ethtool_link_ksettings *cmd)
1531a88394cfSJeff Kirsher {
1532a88394cfSJeff Kirsher u32 new_media;
1533a88394cfSJeff Kirsher unsigned int media_lock;
153441a65f70SPhilippe Reynes u8 duplex = cmd->base.duplex;
153541a65f70SPhilippe Reynes u8 port = cmd->base.port;
153641a65f70SPhilippe Reynes u8 autoneg = cmd->base.autoneg;
153741a65f70SPhilippe Reynes u32 advertising;
1538a88394cfSJeff Kirsher
153941a65f70SPhilippe Reynes ethtool_convert_link_mode_to_legacy_u32(&advertising,
154041a65f70SPhilippe Reynes cmd->link_modes.advertising);
154141a65f70SPhilippe Reynes
154241a65f70SPhilippe Reynes if (cmd->base.speed != 10)
1543a88394cfSJeff Kirsher return -EINVAL;
154441a65f70SPhilippe Reynes if (duplex != DUPLEX_HALF && duplex != DUPLEX_FULL)
1545a88394cfSJeff Kirsher return -EINVAL;
154641a65f70SPhilippe Reynes if (port != PORT_TP && port != PORT_AUI && port != PORT_BNC)
1547a88394cfSJeff Kirsher return -EINVAL;
154841a65f70SPhilippe Reynes if (de->de21040 && port == PORT_BNC)
1549a88394cfSJeff Kirsher return -EINVAL;
155041a65f70SPhilippe Reynes if (autoneg != AUTONEG_DISABLE && autoneg != AUTONEG_ENABLE)
1551a88394cfSJeff Kirsher return -EINVAL;
155241a65f70SPhilippe Reynes if (advertising & ~de->media_supported)
1553a88394cfSJeff Kirsher return -EINVAL;
155441a65f70SPhilippe Reynes if (autoneg == AUTONEG_ENABLE &&
155541a65f70SPhilippe Reynes (!(advertising & ADVERTISED_Autoneg)))
1556a88394cfSJeff Kirsher return -EINVAL;
1557a88394cfSJeff Kirsher
155841a65f70SPhilippe Reynes switch (port) {
1559a88394cfSJeff Kirsher case PORT_AUI:
1560a88394cfSJeff Kirsher new_media = DE_MEDIA_AUI;
156141a65f70SPhilippe Reynes if (!(advertising & ADVERTISED_AUI))
1562a88394cfSJeff Kirsher return -EINVAL;
1563a88394cfSJeff Kirsher break;
1564a88394cfSJeff Kirsher case PORT_BNC:
1565a88394cfSJeff Kirsher new_media = DE_MEDIA_BNC;
156641a65f70SPhilippe Reynes if (!(advertising & ADVERTISED_BNC))
1567a88394cfSJeff Kirsher return -EINVAL;
1568a88394cfSJeff Kirsher break;
1569a88394cfSJeff Kirsher default:
157041a65f70SPhilippe Reynes if (autoneg == AUTONEG_ENABLE)
1571a88394cfSJeff Kirsher new_media = DE_MEDIA_TP_AUTO;
157241a65f70SPhilippe Reynes else if (duplex == DUPLEX_FULL)
1573a88394cfSJeff Kirsher new_media = DE_MEDIA_TP_FD;
1574a88394cfSJeff Kirsher else
1575a88394cfSJeff Kirsher new_media = DE_MEDIA_TP;
157641a65f70SPhilippe Reynes if (!(advertising & ADVERTISED_TP))
1577a88394cfSJeff Kirsher return -EINVAL;
157841a65f70SPhilippe Reynes if (!(advertising & (ADVERTISED_10baseT_Full |
157941a65f70SPhilippe Reynes ADVERTISED_10baseT_Half)))
1580a88394cfSJeff Kirsher return -EINVAL;
1581a88394cfSJeff Kirsher break;
1582a88394cfSJeff Kirsher }
1583a88394cfSJeff Kirsher
158441a65f70SPhilippe Reynes media_lock = (autoneg == AUTONEG_ENABLE) ? 0 : 1;
1585a88394cfSJeff Kirsher
1586a88394cfSJeff Kirsher if ((new_media == de->media_type) &&
1587a88394cfSJeff Kirsher (media_lock == de->media_lock) &&
158841a65f70SPhilippe Reynes (advertising == de->media_advertise))
1589a88394cfSJeff Kirsher return 0; /* nothing to change */
1590a88394cfSJeff Kirsher
1591a88394cfSJeff Kirsher de_link_down(de);
1592a88394cfSJeff Kirsher mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK);
1593a88394cfSJeff Kirsher de_stop_rxtx(de);
1594a88394cfSJeff Kirsher
1595a88394cfSJeff Kirsher de->media_type = new_media;
1596a88394cfSJeff Kirsher de->media_lock = media_lock;
159741a65f70SPhilippe Reynes de->media_advertise = advertising;
1598a88394cfSJeff Kirsher de_set_media(de);
1599a88394cfSJeff Kirsher if (netif_running(de->dev))
1600a88394cfSJeff Kirsher de_start_rxtx(de);
1601a88394cfSJeff Kirsher
1602a88394cfSJeff Kirsher return 0;
1603a88394cfSJeff Kirsher }
1604a88394cfSJeff Kirsher
de_get_drvinfo(struct net_device * dev,struct ethtool_drvinfo * info)1605a88394cfSJeff Kirsher static void de_get_drvinfo (struct net_device *dev,struct ethtool_drvinfo *info)
1606a88394cfSJeff Kirsher {
1607a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1608a88394cfSJeff Kirsher
1609f029c781SWolfram Sang strscpy(info->driver, DRV_NAME, sizeof(info->driver));
1610f029c781SWolfram Sang strscpy(info->bus_info, pci_name(de->pdev), sizeof(info->bus_info));
1611a88394cfSJeff Kirsher }
1612a88394cfSJeff Kirsher
de_get_regs_len(struct net_device * dev)1613a88394cfSJeff Kirsher static int de_get_regs_len(struct net_device *dev)
1614a88394cfSJeff Kirsher {
1615a88394cfSJeff Kirsher return DE_REGS_SIZE;
1616a88394cfSJeff Kirsher }
1617a88394cfSJeff Kirsher
de_get_link_ksettings(struct net_device * dev,struct ethtool_link_ksettings * cmd)161841a65f70SPhilippe Reynes static int de_get_link_ksettings(struct net_device *dev,
161941a65f70SPhilippe Reynes struct ethtool_link_ksettings *cmd)
1620a88394cfSJeff Kirsher {
1621a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1622a88394cfSJeff Kirsher
1623a88394cfSJeff Kirsher spin_lock_irq(&de->lock);
1624c7c6b871Syuval.shaia@oracle.com __de_get_link_ksettings(de, cmd);
1625a88394cfSJeff Kirsher spin_unlock_irq(&de->lock);
1626a88394cfSJeff Kirsher
1627c7c6b871Syuval.shaia@oracle.com return 0;
1628a88394cfSJeff Kirsher }
1629a88394cfSJeff Kirsher
de_set_link_ksettings(struct net_device * dev,const struct ethtool_link_ksettings * cmd)163041a65f70SPhilippe Reynes static int de_set_link_ksettings(struct net_device *dev,
163141a65f70SPhilippe Reynes const struct ethtool_link_ksettings *cmd)
1632a88394cfSJeff Kirsher {
1633a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1634a88394cfSJeff Kirsher int rc;
1635a88394cfSJeff Kirsher
1636a88394cfSJeff Kirsher spin_lock_irq(&de->lock);
163741a65f70SPhilippe Reynes rc = __de_set_link_ksettings(de, cmd);
1638a88394cfSJeff Kirsher spin_unlock_irq(&de->lock);
1639a88394cfSJeff Kirsher
1640a88394cfSJeff Kirsher return rc;
1641a88394cfSJeff Kirsher }
1642a88394cfSJeff Kirsher
de_get_msglevel(struct net_device * dev)1643a88394cfSJeff Kirsher static u32 de_get_msglevel(struct net_device *dev)
1644a88394cfSJeff Kirsher {
1645a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1646a88394cfSJeff Kirsher
1647a88394cfSJeff Kirsher return de->msg_enable;
1648a88394cfSJeff Kirsher }
1649a88394cfSJeff Kirsher
de_set_msglevel(struct net_device * dev,u32 msglvl)1650a88394cfSJeff Kirsher static void de_set_msglevel(struct net_device *dev, u32 msglvl)
1651a88394cfSJeff Kirsher {
1652a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1653a88394cfSJeff Kirsher
1654a88394cfSJeff Kirsher de->msg_enable = msglvl;
1655a88394cfSJeff Kirsher }
1656a88394cfSJeff Kirsher
de_get_eeprom(struct net_device * dev,struct ethtool_eeprom * eeprom,u8 * data)1657a88394cfSJeff Kirsher static int de_get_eeprom(struct net_device *dev,
1658a88394cfSJeff Kirsher struct ethtool_eeprom *eeprom, u8 *data)
1659a88394cfSJeff Kirsher {
1660a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1661a88394cfSJeff Kirsher
1662a88394cfSJeff Kirsher if (!de->ee_data)
1663a88394cfSJeff Kirsher return -EOPNOTSUPP;
1664a88394cfSJeff Kirsher if ((eeprom->offset != 0) || (eeprom->magic != 0) ||
1665a88394cfSJeff Kirsher (eeprom->len != DE_EEPROM_SIZE))
1666a88394cfSJeff Kirsher return -EINVAL;
1667a88394cfSJeff Kirsher memcpy(data, de->ee_data, eeprom->len);
1668a88394cfSJeff Kirsher
1669a88394cfSJeff Kirsher return 0;
1670a88394cfSJeff Kirsher }
1671a88394cfSJeff Kirsher
de_nway_reset(struct net_device * dev)1672a88394cfSJeff Kirsher static int de_nway_reset(struct net_device *dev)
1673a88394cfSJeff Kirsher {
1674a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1675a88394cfSJeff Kirsher u32 status;
1676a88394cfSJeff Kirsher
1677a88394cfSJeff Kirsher if (de->media_type != DE_MEDIA_TP_AUTO)
1678a88394cfSJeff Kirsher return -EINVAL;
1679a88394cfSJeff Kirsher if (netif_carrier_ok(de->dev))
1680a88394cfSJeff Kirsher de_link_down(de);
1681a88394cfSJeff Kirsher
1682a88394cfSJeff Kirsher status = dr32(SIAStatus);
1683a88394cfSJeff Kirsher dw32(SIAStatus, (status & ~NWayState) | NWayRestart);
1684a88394cfSJeff Kirsher netif_info(de, link, dev, "link nway restart, status %x,%x\n",
1685a88394cfSJeff Kirsher status, dr32(SIAStatus));
1686a88394cfSJeff Kirsher return 0;
1687a88394cfSJeff Kirsher }
1688a88394cfSJeff Kirsher
de_get_regs(struct net_device * dev,struct ethtool_regs * regs,void * data)1689a88394cfSJeff Kirsher static void de_get_regs(struct net_device *dev, struct ethtool_regs *regs,
1690a88394cfSJeff Kirsher void *data)
1691a88394cfSJeff Kirsher {
1692a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
1693a88394cfSJeff Kirsher
1694a88394cfSJeff Kirsher regs->version = (DE_REGS_VER << 2) | de->de21040;
1695a88394cfSJeff Kirsher
1696a88394cfSJeff Kirsher spin_lock_irq(&de->lock);
1697a88394cfSJeff Kirsher __de_get_regs(de, data);
1698a88394cfSJeff Kirsher spin_unlock_irq(&de->lock);
1699a88394cfSJeff Kirsher }
1700a88394cfSJeff Kirsher
1701a88394cfSJeff Kirsher static const struct ethtool_ops de_ethtool_ops = {
1702a88394cfSJeff Kirsher .get_link = ethtool_op_get_link,
1703a88394cfSJeff Kirsher .get_drvinfo = de_get_drvinfo,
1704a88394cfSJeff Kirsher .get_regs_len = de_get_regs_len,
1705a88394cfSJeff Kirsher .get_msglevel = de_get_msglevel,
1706a88394cfSJeff Kirsher .set_msglevel = de_set_msglevel,
1707a88394cfSJeff Kirsher .get_eeprom = de_get_eeprom,
1708a88394cfSJeff Kirsher .nway_reset = de_nway_reset,
1709a88394cfSJeff Kirsher .get_regs = de_get_regs,
171041a65f70SPhilippe Reynes .get_link_ksettings = de_get_link_ksettings,
171141a65f70SPhilippe Reynes .set_link_ksettings = de_set_link_ksettings,
1712a88394cfSJeff Kirsher };
1713a88394cfSJeff Kirsher
de21040_get_mac_address(struct de_private * de)1714779c1a85SBill Pemberton static void de21040_get_mac_address(struct de_private *de)
1715a88394cfSJeff Kirsher {
1716ca879317SJakub Kicinski u8 addr[ETH_ALEN];
1717a88394cfSJeff Kirsher unsigned i;
1718a88394cfSJeff Kirsher
1719a88394cfSJeff Kirsher dw32 (ROMCmd, 0); /* Reset the pointer with a dummy write. */
1720a88394cfSJeff Kirsher udelay(5);
1721a88394cfSJeff Kirsher
1722a88394cfSJeff Kirsher for (i = 0; i < 6; i++) {
1723a88394cfSJeff Kirsher int value, boguscnt = 100000;
1724a88394cfSJeff Kirsher do {
1725a88394cfSJeff Kirsher value = dr32(ROMCmd);
1726a88394cfSJeff Kirsher rmb();
1727a88394cfSJeff Kirsher } while (value < 0 && --boguscnt > 0);
1728ca879317SJakub Kicinski addr[i] = value;
1729a88394cfSJeff Kirsher udelay(1);
1730a88394cfSJeff Kirsher if (boguscnt <= 0)
1731a88394cfSJeff Kirsher pr_warn("timeout reading 21040 MAC address byte %u\n",
1732a88394cfSJeff Kirsher i);
1733a88394cfSJeff Kirsher }
1734ca879317SJakub Kicinski eth_hw_addr_set(de->dev, addr);
1735a88394cfSJeff Kirsher }
1736a88394cfSJeff Kirsher
de21040_get_media_info(struct de_private * de)1737779c1a85SBill Pemberton static void de21040_get_media_info(struct de_private *de)
1738a88394cfSJeff Kirsher {
1739a88394cfSJeff Kirsher unsigned int i;
1740a88394cfSJeff Kirsher
1741a88394cfSJeff Kirsher de->media_type = DE_MEDIA_TP;
1742a88394cfSJeff Kirsher de->media_supported |= SUPPORTED_TP | SUPPORTED_10baseT_Full |
1743a88394cfSJeff Kirsher SUPPORTED_10baseT_Half | SUPPORTED_AUI;
1744a88394cfSJeff Kirsher de->media_advertise = de->media_supported;
1745a88394cfSJeff Kirsher
1746a88394cfSJeff Kirsher for (i = 0; i < DE_MAX_MEDIA; i++) {
1747a88394cfSJeff Kirsher switch (i) {
1748a88394cfSJeff Kirsher case DE_MEDIA_AUI:
1749a88394cfSJeff Kirsher case DE_MEDIA_TP:
1750a88394cfSJeff Kirsher case DE_MEDIA_TP_FD:
1751a88394cfSJeff Kirsher de->media[i].type = i;
1752a88394cfSJeff Kirsher de->media[i].csr13 = t21040_csr13[i];
1753a88394cfSJeff Kirsher de->media[i].csr14 = t21040_csr14[i];
1754a88394cfSJeff Kirsher de->media[i].csr15 = t21040_csr15[i];
1755a88394cfSJeff Kirsher break;
1756a88394cfSJeff Kirsher default:
1757a88394cfSJeff Kirsher de->media[i].type = DE_MEDIA_INVALID;
1758a88394cfSJeff Kirsher break;
1759a88394cfSJeff Kirsher }
1760a88394cfSJeff Kirsher }
1761a88394cfSJeff Kirsher }
1762a88394cfSJeff Kirsher
1763a88394cfSJeff Kirsher /* Note: this routine returns extra data bits for size detection. */
tulip_read_eeprom(void __iomem * regs,int location,int addr_len)1764779c1a85SBill Pemberton static unsigned tulip_read_eeprom(void __iomem *regs, int location,
1765779c1a85SBill Pemberton int addr_len)
1766a88394cfSJeff Kirsher {
1767a88394cfSJeff Kirsher int i;
1768a88394cfSJeff Kirsher unsigned retval = 0;
1769a88394cfSJeff Kirsher void __iomem *ee_addr = regs + ROMCmd;
1770a88394cfSJeff Kirsher int read_cmd = location | (EE_READ_CMD << addr_len);
1771a88394cfSJeff Kirsher
1772a88394cfSJeff Kirsher writel(EE_ENB & ~EE_CS, ee_addr);
1773a88394cfSJeff Kirsher writel(EE_ENB, ee_addr);
1774a88394cfSJeff Kirsher
1775a88394cfSJeff Kirsher /* Shift the read command bits out. */
1776a88394cfSJeff Kirsher for (i = 4 + addr_len; i >= 0; i--) {
1777a88394cfSJeff Kirsher short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
1778a88394cfSJeff Kirsher writel(EE_ENB | dataval, ee_addr);
1779a88394cfSJeff Kirsher readl(ee_addr);
1780a88394cfSJeff Kirsher writel(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
1781a88394cfSJeff Kirsher readl(ee_addr);
1782a88394cfSJeff Kirsher retval = (retval << 1) | ((readl(ee_addr) & EE_DATA_READ) ? 1 : 0);
1783a88394cfSJeff Kirsher }
1784a88394cfSJeff Kirsher writel(EE_ENB, ee_addr);
1785a88394cfSJeff Kirsher readl(ee_addr);
1786a88394cfSJeff Kirsher
1787a88394cfSJeff Kirsher for (i = 16; i > 0; i--) {
1788a88394cfSJeff Kirsher writel(EE_ENB | EE_SHIFT_CLK, ee_addr);
1789a88394cfSJeff Kirsher readl(ee_addr);
1790a88394cfSJeff Kirsher retval = (retval << 1) | ((readl(ee_addr) & EE_DATA_READ) ? 1 : 0);
1791a88394cfSJeff Kirsher writel(EE_ENB, ee_addr);
1792a88394cfSJeff Kirsher readl(ee_addr);
1793a88394cfSJeff Kirsher }
1794a88394cfSJeff Kirsher
1795a88394cfSJeff Kirsher /* Terminate the EEPROM access. */
1796a88394cfSJeff Kirsher writel(EE_ENB & ~EE_CS, ee_addr);
1797a88394cfSJeff Kirsher return retval;
1798a88394cfSJeff Kirsher }
1799a88394cfSJeff Kirsher
de21041_get_srom_info(struct de_private * de)1800779c1a85SBill Pemberton static void de21041_get_srom_info(struct de_private *de)
1801a88394cfSJeff Kirsher {
1802a88394cfSJeff Kirsher unsigned i, sa_offset = 0, ofs;
1803a88394cfSJeff Kirsher u8 ee_data[DE_EEPROM_SIZE + 6] = {};
1804a88394cfSJeff Kirsher unsigned ee_addr_size = tulip_read_eeprom(de->regs, 0xff, 8) & 0x40000 ? 8 : 6;
1805a88394cfSJeff Kirsher struct de_srom_info_leaf *il;
1806a88394cfSJeff Kirsher void *bufp;
1807a88394cfSJeff Kirsher
1808a88394cfSJeff Kirsher /* download entire eeprom */
1809a88394cfSJeff Kirsher for (i = 0; i < DE_EEPROM_WORDS; i++)
1810a88394cfSJeff Kirsher ((__le16 *)ee_data)[i] =
1811a88394cfSJeff Kirsher cpu_to_le16(tulip_read_eeprom(de->regs, i, ee_addr_size));
1812a88394cfSJeff Kirsher
1813a88394cfSJeff Kirsher /* DEC now has a specification but early board makers
1814a88394cfSJeff Kirsher just put the address in the first EEPROM locations. */
1815a88394cfSJeff Kirsher /* This does memcmp(eedata, eedata+16, 8) */
1816a88394cfSJeff Kirsher
1817a88394cfSJeff Kirsher #ifndef CONFIG_MIPS_COBALT
1818a88394cfSJeff Kirsher
1819a88394cfSJeff Kirsher for (i = 0; i < 8; i ++)
1820a88394cfSJeff Kirsher if (ee_data[i] != ee_data[16+i])
1821a88394cfSJeff Kirsher sa_offset = 20;
1822a88394cfSJeff Kirsher
1823a88394cfSJeff Kirsher #endif
1824a88394cfSJeff Kirsher
1825a88394cfSJeff Kirsher /* store MAC address */
182625b90c19SJakub Kicinski eth_hw_addr_set(de->dev, &ee_data[sa_offset]);
1827a88394cfSJeff Kirsher
1828a88394cfSJeff Kirsher /* get offset of controller 0 info leaf. ignore 2nd byte. */
1829a88394cfSJeff Kirsher ofs = ee_data[SROMC0InfoLeaf];
1830a88394cfSJeff Kirsher if (ofs >= (sizeof(ee_data) - sizeof(struct de_srom_info_leaf) - sizeof(struct de_srom_media_block)))
1831a88394cfSJeff Kirsher goto bad_srom;
1832a88394cfSJeff Kirsher
1833a88394cfSJeff Kirsher /* get pointer to info leaf */
1834a88394cfSJeff Kirsher il = (struct de_srom_info_leaf *) &ee_data[ofs];
1835a88394cfSJeff Kirsher
1836a88394cfSJeff Kirsher /* paranoia checks */
1837a88394cfSJeff Kirsher if (il->n_blocks == 0)
1838a88394cfSJeff Kirsher goto bad_srom;
1839a88394cfSJeff Kirsher if ((sizeof(ee_data) - ofs) <
1840a88394cfSJeff Kirsher (sizeof(struct de_srom_info_leaf) + (sizeof(struct de_srom_media_block) * il->n_blocks)))
1841a88394cfSJeff Kirsher goto bad_srom;
1842a88394cfSJeff Kirsher
1843a88394cfSJeff Kirsher /* get default media type */
1844a88394cfSJeff Kirsher switch (get_unaligned(&il->default_media)) {
1845a88394cfSJeff Kirsher case 0x0001: de->media_type = DE_MEDIA_BNC; break;
1846a88394cfSJeff Kirsher case 0x0002: de->media_type = DE_MEDIA_AUI; break;
1847a88394cfSJeff Kirsher case 0x0204: de->media_type = DE_MEDIA_TP_FD; break;
1848a88394cfSJeff Kirsher default: de->media_type = DE_MEDIA_TP_AUTO; break;
1849a88394cfSJeff Kirsher }
1850a88394cfSJeff Kirsher
1851a88394cfSJeff Kirsher if (netif_msg_probe(de))
1852a88394cfSJeff Kirsher pr_info("de%d: SROM leaf offset %u, default media %s\n",
1853a88394cfSJeff Kirsher de->board_idx, ofs, media_name[de->media_type]);
1854a88394cfSJeff Kirsher
1855a88394cfSJeff Kirsher /* init SIA register values to defaults */
1856a88394cfSJeff Kirsher for (i = 0; i < DE_MAX_MEDIA; i++) {
1857a88394cfSJeff Kirsher de->media[i].type = DE_MEDIA_INVALID;
1858a88394cfSJeff Kirsher de->media[i].csr13 = 0xffff;
1859a88394cfSJeff Kirsher de->media[i].csr14 = 0xffff;
1860a88394cfSJeff Kirsher de->media[i].csr15 = 0xffff;
1861a88394cfSJeff Kirsher }
1862a88394cfSJeff Kirsher
1863a88394cfSJeff Kirsher /* parse media blocks to see what medias are supported,
1864a88394cfSJeff Kirsher * and if any custom CSR values are provided
1865a88394cfSJeff Kirsher */
1866a88394cfSJeff Kirsher bufp = ((void *)il) + sizeof(*il);
1867a88394cfSJeff Kirsher for (i = 0; i < il->n_blocks; i++) {
1868a88394cfSJeff Kirsher struct de_srom_media_block *ib = bufp;
1869a88394cfSJeff Kirsher unsigned idx;
1870a88394cfSJeff Kirsher
1871a88394cfSJeff Kirsher /* index based on media type in media block */
1872a88394cfSJeff Kirsher switch(ib->opts & MediaBlockMask) {
1873a88394cfSJeff Kirsher case 0: /* 10baseT */
1874a88394cfSJeff Kirsher de->media_supported |= SUPPORTED_TP | SUPPORTED_10baseT_Half
1875a88394cfSJeff Kirsher | SUPPORTED_Autoneg;
1876a88394cfSJeff Kirsher idx = DE_MEDIA_TP;
1877a88394cfSJeff Kirsher de->media[DE_MEDIA_TP_AUTO].type = DE_MEDIA_TP_AUTO;
1878a88394cfSJeff Kirsher break;
1879a88394cfSJeff Kirsher case 1: /* BNC */
1880a88394cfSJeff Kirsher de->media_supported |= SUPPORTED_BNC;
1881a88394cfSJeff Kirsher idx = DE_MEDIA_BNC;
1882a88394cfSJeff Kirsher break;
1883a88394cfSJeff Kirsher case 2: /* AUI */
1884a88394cfSJeff Kirsher de->media_supported |= SUPPORTED_AUI;
1885a88394cfSJeff Kirsher idx = DE_MEDIA_AUI;
1886a88394cfSJeff Kirsher break;
1887a88394cfSJeff Kirsher case 4: /* 10baseT-FD */
1888a88394cfSJeff Kirsher de->media_supported |= SUPPORTED_TP | SUPPORTED_10baseT_Full
1889a88394cfSJeff Kirsher | SUPPORTED_Autoneg;
1890a88394cfSJeff Kirsher idx = DE_MEDIA_TP_FD;
1891a88394cfSJeff Kirsher de->media[DE_MEDIA_TP_AUTO].type = DE_MEDIA_TP_AUTO;
1892a88394cfSJeff Kirsher break;
1893a88394cfSJeff Kirsher default:
1894a88394cfSJeff Kirsher goto bad_srom;
1895a88394cfSJeff Kirsher }
1896a88394cfSJeff Kirsher
1897a88394cfSJeff Kirsher de->media[idx].type = idx;
1898a88394cfSJeff Kirsher
1899a88394cfSJeff Kirsher if (netif_msg_probe(de))
1900a88394cfSJeff Kirsher pr_info("de%d: media block #%u: %s",
1901a88394cfSJeff Kirsher de->board_idx, i,
1902a88394cfSJeff Kirsher media_name[de->media[idx].type]);
1903a88394cfSJeff Kirsher
1904a88394cfSJeff Kirsher bufp += sizeof (ib->opts);
1905a88394cfSJeff Kirsher
1906a88394cfSJeff Kirsher if (ib->opts & MediaCustomCSRs) {
1907a88394cfSJeff Kirsher de->media[idx].csr13 = get_unaligned(&ib->csr13);
1908a88394cfSJeff Kirsher de->media[idx].csr14 = get_unaligned(&ib->csr14);
1909a88394cfSJeff Kirsher de->media[idx].csr15 = get_unaligned(&ib->csr15);
1910a88394cfSJeff Kirsher bufp += sizeof(ib->csr13) + sizeof(ib->csr14) +
1911a88394cfSJeff Kirsher sizeof(ib->csr15);
1912a88394cfSJeff Kirsher
1913a88394cfSJeff Kirsher if (netif_msg_probe(de))
1914a88394cfSJeff Kirsher pr_cont(" (%x,%x,%x)\n",
1915a88394cfSJeff Kirsher de->media[idx].csr13,
1916a88394cfSJeff Kirsher de->media[idx].csr14,
1917a88394cfSJeff Kirsher de->media[idx].csr15);
1918a88394cfSJeff Kirsher
1919a88394cfSJeff Kirsher } else {
1920a88394cfSJeff Kirsher if (netif_msg_probe(de))
1921a88394cfSJeff Kirsher pr_cont("\n");
1922a88394cfSJeff Kirsher }
1923a88394cfSJeff Kirsher
1924a88394cfSJeff Kirsher if (bufp > ((void *)&ee_data[DE_EEPROM_SIZE - 3]))
1925a88394cfSJeff Kirsher break;
1926a88394cfSJeff Kirsher }
1927a88394cfSJeff Kirsher
1928a88394cfSJeff Kirsher de->media_advertise = de->media_supported;
1929a88394cfSJeff Kirsher
1930a88394cfSJeff Kirsher fill_defaults:
1931a88394cfSJeff Kirsher /* fill in defaults, for cases where custom CSRs not used */
1932a88394cfSJeff Kirsher for (i = 0; i < DE_MAX_MEDIA; i++) {
1933a88394cfSJeff Kirsher if (de->media[i].csr13 == 0xffff)
1934a88394cfSJeff Kirsher de->media[i].csr13 = t21041_csr13[i];
1935a88394cfSJeff Kirsher if (de->media[i].csr14 == 0xffff) {
1936a88394cfSJeff Kirsher /* autonegotiation is broken at least on some chip
1937a88394cfSJeff Kirsher revisions - rev. 0x21 works, 0x11 does not */
1938a88394cfSJeff Kirsher if (de->pdev->revision < 0x20)
1939a88394cfSJeff Kirsher de->media[i].csr14 = t21041_csr14_brk[i];
1940a88394cfSJeff Kirsher else
1941a88394cfSJeff Kirsher de->media[i].csr14 = t21041_csr14[i];
1942a88394cfSJeff Kirsher }
1943a88394cfSJeff Kirsher if (de->media[i].csr15 == 0xffff)
1944a88394cfSJeff Kirsher de->media[i].csr15 = t21041_csr15[i];
1945a88394cfSJeff Kirsher }
1946a88394cfSJeff Kirsher
1947a88394cfSJeff Kirsher de->ee_data = kmemdup(&ee_data[0], DE_EEPROM_SIZE, GFP_KERNEL);
1948a88394cfSJeff Kirsher
1949a88394cfSJeff Kirsher return;
1950a88394cfSJeff Kirsher
1951a88394cfSJeff Kirsher bad_srom:
1952a88394cfSJeff Kirsher /* for error cases, it's ok to assume we support all these */
1953a88394cfSJeff Kirsher for (i = 0; i < DE_MAX_MEDIA; i++)
1954a88394cfSJeff Kirsher de->media[i].type = i;
1955a88394cfSJeff Kirsher de->media_supported =
1956a88394cfSJeff Kirsher SUPPORTED_10baseT_Half |
1957a88394cfSJeff Kirsher SUPPORTED_10baseT_Full |
1958a88394cfSJeff Kirsher SUPPORTED_Autoneg |
1959a88394cfSJeff Kirsher SUPPORTED_TP |
1960a88394cfSJeff Kirsher SUPPORTED_AUI |
1961a88394cfSJeff Kirsher SUPPORTED_BNC;
1962a88394cfSJeff Kirsher goto fill_defaults;
1963a88394cfSJeff Kirsher }
1964a88394cfSJeff Kirsher
1965a88394cfSJeff Kirsher static const struct net_device_ops de_netdev_ops = {
1966a88394cfSJeff Kirsher .ndo_open = de_open,
1967a88394cfSJeff Kirsher .ndo_stop = de_close,
1968afc4b13dSJiri Pirko .ndo_set_rx_mode = de_set_rx_mode,
1969a88394cfSJeff Kirsher .ndo_start_xmit = de_start_xmit,
1970a88394cfSJeff Kirsher .ndo_get_stats = de_get_stats,
1971a88394cfSJeff Kirsher .ndo_tx_timeout = de_tx_timeout,
1972a88394cfSJeff Kirsher .ndo_set_mac_address = eth_mac_addr,
1973a88394cfSJeff Kirsher .ndo_validate_addr = eth_validate_addr,
1974a88394cfSJeff Kirsher };
1975a88394cfSJeff Kirsher
de_init_one(struct pci_dev * pdev,const struct pci_device_id * ent)19761dd06ae8SGreg Kroah-Hartman static int de_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1977a88394cfSJeff Kirsher {
1978a88394cfSJeff Kirsher struct net_device *dev;
1979a88394cfSJeff Kirsher struct de_private *de;
1980a88394cfSJeff Kirsher int rc;
1981a88394cfSJeff Kirsher void __iomem *regs;
1982a88394cfSJeff Kirsher unsigned long pciaddr;
1983a88394cfSJeff Kirsher static int board_idx = -1;
1984a88394cfSJeff Kirsher
1985a88394cfSJeff Kirsher board_idx++;
1986a88394cfSJeff Kirsher
1987a88394cfSJeff Kirsher /* allocate a new ethernet device structure, and fill in defaults */
1988a88394cfSJeff Kirsher dev = alloc_etherdev(sizeof(struct de_private));
1989a88394cfSJeff Kirsher if (!dev)
1990a88394cfSJeff Kirsher return -ENOMEM;
1991a88394cfSJeff Kirsher
1992a88394cfSJeff Kirsher dev->netdev_ops = &de_netdev_ops;
1993a88394cfSJeff Kirsher SET_NETDEV_DEV(dev, &pdev->dev);
1994a88394cfSJeff Kirsher dev->ethtool_ops = &de_ethtool_ops;
1995a88394cfSJeff Kirsher dev->watchdog_timeo = TX_TIMEOUT;
1996a88394cfSJeff Kirsher
1997a88394cfSJeff Kirsher de = netdev_priv(dev);
1998a88394cfSJeff Kirsher de->de21040 = ent->driver_data == 0 ? 1 : 0;
1999a88394cfSJeff Kirsher de->pdev = pdev;
2000a88394cfSJeff Kirsher de->dev = dev;
2001a88394cfSJeff Kirsher de->msg_enable = (debug < 0 ? DE_DEF_MSG_ENABLE : debug);
2002a88394cfSJeff Kirsher de->board_idx = board_idx;
2003a88394cfSJeff Kirsher spin_lock_init (&de->lock);
200441fce703SKees Cook timer_setup(&de->media_timer,
200541fce703SKees Cook de->de21040 ? de21040_media_timer : de21041_media_timer,
200641fce703SKees Cook 0);
2007a88394cfSJeff Kirsher
2008a88394cfSJeff Kirsher netif_carrier_off(dev);
2009a88394cfSJeff Kirsher
2010a88394cfSJeff Kirsher /* wake up device, assign resources */
2011a88394cfSJeff Kirsher rc = pci_enable_device(pdev);
2012a88394cfSJeff Kirsher if (rc)
2013a88394cfSJeff Kirsher goto err_out_free;
2014a88394cfSJeff Kirsher
2015a88394cfSJeff Kirsher /* reserve PCI resources to ensure driver atomicity */
2016a88394cfSJeff Kirsher rc = pci_request_regions(pdev, DRV_NAME);
2017a88394cfSJeff Kirsher if (rc)
2018a88394cfSJeff Kirsher goto err_out_disable;
2019a88394cfSJeff Kirsher
2020a88394cfSJeff Kirsher /* check for invalid IRQ value */
2021a88394cfSJeff Kirsher if (pdev->irq < 2) {
2022a88394cfSJeff Kirsher rc = -EIO;
2023a88394cfSJeff Kirsher pr_err("invalid irq (%d) for pci dev %s\n",
2024a88394cfSJeff Kirsher pdev->irq, pci_name(pdev));
2025a88394cfSJeff Kirsher goto err_out_res;
2026a88394cfSJeff Kirsher }
2027a88394cfSJeff Kirsher
2028a88394cfSJeff Kirsher /* obtain and check validity of PCI I/O address */
2029a88394cfSJeff Kirsher pciaddr = pci_resource_start(pdev, 1);
2030a88394cfSJeff Kirsher if (!pciaddr) {
2031a88394cfSJeff Kirsher rc = -EIO;
2032a88394cfSJeff Kirsher pr_err("no MMIO resource for pci dev %s\n", pci_name(pdev));
2033a88394cfSJeff Kirsher goto err_out_res;
2034a88394cfSJeff Kirsher }
2035a88394cfSJeff Kirsher if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) {
2036a88394cfSJeff Kirsher rc = -EIO;
2037a88394cfSJeff Kirsher pr_err("MMIO resource (%llx) too small on pci dev %s\n",
2038a88394cfSJeff Kirsher (unsigned long long)pci_resource_len(pdev, 1),
2039a88394cfSJeff Kirsher pci_name(pdev));
2040a88394cfSJeff Kirsher goto err_out_res;
2041a88394cfSJeff Kirsher }
2042a88394cfSJeff Kirsher
2043a88394cfSJeff Kirsher /* remap CSR registers */
20444bdc0d67SChristoph Hellwig regs = ioremap(pciaddr, DE_REGS_SIZE);
2045a88394cfSJeff Kirsher if (!regs) {
2046a88394cfSJeff Kirsher rc = -EIO;
2047a88394cfSJeff Kirsher pr_err("Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n",
2048a88394cfSJeff Kirsher (unsigned long long)pci_resource_len(pdev, 1),
2049a88394cfSJeff Kirsher pciaddr, pci_name(pdev));
2050a88394cfSJeff Kirsher goto err_out_res;
2051a88394cfSJeff Kirsher }
2052a88394cfSJeff Kirsher de->regs = regs;
2053a88394cfSJeff Kirsher
2054a88394cfSJeff Kirsher de_adapter_wake(de);
2055a88394cfSJeff Kirsher
2056a88394cfSJeff Kirsher /* make sure hardware is not running */
2057a88394cfSJeff Kirsher rc = de_reset_mac(de);
2058a88394cfSJeff Kirsher if (rc) {
2059a88394cfSJeff Kirsher pr_err("Cannot reset MAC, pci dev %s\n", pci_name(pdev));
2060a88394cfSJeff Kirsher goto err_out_iomap;
2061a88394cfSJeff Kirsher }
2062a88394cfSJeff Kirsher
2063a88394cfSJeff Kirsher /* get MAC address, initialize default media type and
2064a88394cfSJeff Kirsher * get list of supported media
2065a88394cfSJeff Kirsher */
2066a88394cfSJeff Kirsher if (de->de21040) {
2067a88394cfSJeff Kirsher de21040_get_mac_address(de);
2068a88394cfSJeff Kirsher de21040_get_media_info(de);
2069a88394cfSJeff Kirsher } else {
2070a88394cfSJeff Kirsher de21041_get_srom_info(de);
2071a88394cfSJeff Kirsher }
2072a88394cfSJeff Kirsher
2073a88394cfSJeff Kirsher /* register new network interface with kernel */
2074a88394cfSJeff Kirsher rc = register_netdev(dev);
2075a88394cfSJeff Kirsher if (rc)
2076a88394cfSJeff Kirsher goto err_out_iomap;
2077a88394cfSJeff Kirsher
2078a88394cfSJeff Kirsher /* print info about board and interface just registered */
2079308f2888SFrancois Romieu netdev_info(dev, "%s at %p, %pM, IRQ %d\n",
2080a88394cfSJeff Kirsher de->de21040 ? "21040" : "21041",
2081308f2888SFrancois Romieu regs, dev->dev_addr, pdev->irq);
2082a88394cfSJeff Kirsher
2083a88394cfSJeff Kirsher pci_set_drvdata(pdev, dev);
2084a88394cfSJeff Kirsher
2085a88394cfSJeff Kirsher /* enable busmastering */
2086a88394cfSJeff Kirsher pci_set_master(pdev);
2087a88394cfSJeff Kirsher
2088a88394cfSJeff Kirsher /* put adapter to sleep */
2089a88394cfSJeff Kirsher de_adapter_sleep(de);
2090a88394cfSJeff Kirsher
2091a88394cfSJeff Kirsher return 0;
2092a88394cfSJeff Kirsher
2093a88394cfSJeff Kirsher err_out_iomap:
2094a88394cfSJeff Kirsher kfree(de->ee_data);
2095a88394cfSJeff Kirsher iounmap(regs);
2096a88394cfSJeff Kirsher err_out_res:
2097a88394cfSJeff Kirsher pci_release_regions(pdev);
2098a88394cfSJeff Kirsher err_out_disable:
2099a88394cfSJeff Kirsher pci_disable_device(pdev);
2100a88394cfSJeff Kirsher err_out_free:
2101a88394cfSJeff Kirsher free_netdev(dev);
2102a88394cfSJeff Kirsher return rc;
2103a88394cfSJeff Kirsher }
2104a88394cfSJeff Kirsher
de_remove_one(struct pci_dev * pdev)2105779c1a85SBill Pemberton static void de_remove_one(struct pci_dev *pdev)
2106a88394cfSJeff Kirsher {
2107a88394cfSJeff Kirsher struct net_device *dev = pci_get_drvdata(pdev);
2108a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
2109a88394cfSJeff Kirsher
2110a88394cfSJeff Kirsher BUG_ON(!dev);
2111a88394cfSJeff Kirsher unregister_netdev(dev);
2112a88394cfSJeff Kirsher kfree(de->ee_data);
2113a88394cfSJeff Kirsher iounmap(de->regs);
2114a88394cfSJeff Kirsher pci_release_regions(pdev);
2115a88394cfSJeff Kirsher pci_disable_device(pdev);
2116a88394cfSJeff Kirsher free_netdev(dev);
2117a88394cfSJeff Kirsher }
2118a88394cfSJeff Kirsher
de_suspend(struct device * dev_d)21198cfa989aSVaibhav Gupta static int __maybe_unused de_suspend(struct device *dev_d)
2120a88394cfSJeff Kirsher {
21218cfa989aSVaibhav Gupta struct pci_dev *pdev = to_pci_dev(dev_d);
2122a88394cfSJeff Kirsher struct net_device *dev = pci_get_drvdata(pdev);
2123a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
2124a88394cfSJeff Kirsher
2125a88394cfSJeff Kirsher rtnl_lock();
2126a88394cfSJeff Kirsher if (netif_running (dev)) {
2127308f2888SFrancois Romieu const int irq = pdev->irq;
2128308f2888SFrancois Romieu
2129a88394cfSJeff Kirsher del_timer_sync(&de->media_timer);
2130a88394cfSJeff Kirsher
2131308f2888SFrancois Romieu disable_irq(irq);
2132a88394cfSJeff Kirsher spin_lock_irq(&de->lock);
2133a88394cfSJeff Kirsher
2134a88394cfSJeff Kirsher de_stop_hw(de);
2135a88394cfSJeff Kirsher netif_stop_queue(dev);
2136a88394cfSJeff Kirsher netif_device_detach(dev);
2137a88394cfSJeff Kirsher netif_carrier_off(dev);
2138a88394cfSJeff Kirsher
2139a88394cfSJeff Kirsher spin_unlock_irq(&de->lock);
2140308f2888SFrancois Romieu enable_irq(irq);
2141a88394cfSJeff Kirsher
2142a88394cfSJeff Kirsher /* Update the error counts. */
2143a88394cfSJeff Kirsher __de_get_stats(de);
2144a88394cfSJeff Kirsher
2145308f2888SFrancois Romieu synchronize_irq(irq);
2146a88394cfSJeff Kirsher de_clean_rings(de);
2147a88394cfSJeff Kirsher
2148a88394cfSJeff Kirsher de_adapter_sleep(de);
2149a88394cfSJeff Kirsher } else {
2150a88394cfSJeff Kirsher netif_device_detach(dev);
2151a88394cfSJeff Kirsher }
2152a88394cfSJeff Kirsher rtnl_unlock();
2153a88394cfSJeff Kirsher return 0;
2154a88394cfSJeff Kirsher }
2155a88394cfSJeff Kirsher
de_resume(struct device * dev_d)21568cfa989aSVaibhav Gupta static int __maybe_unused de_resume(struct device *dev_d)
2157a88394cfSJeff Kirsher {
21588cfa989aSVaibhav Gupta struct pci_dev *pdev = to_pci_dev(dev_d);
2159a88394cfSJeff Kirsher struct net_device *dev = pci_get_drvdata(pdev);
2160a88394cfSJeff Kirsher struct de_private *de = netdev_priv(dev);
2161a88394cfSJeff Kirsher
2162a88394cfSJeff Kirsher rtnl_lock();
2163a88394cfSJeff Kirsher if (netif_device_present(dev))
2164a88394cfSJeff Kirsher goto out;
2165a88394cfSJeff Kirsher if (!netif_running(dev))
2166a88394cfSJeff Kirsher goto out_attach;
2167a88394cfSJeff Kirsher pci_set_master(pdev);
2168a88394cfSJeff Kirsher de_init_rings(de);
2169a88394cfSJeff Kirsher de_init_hw(de);
2170a88394cfSJeff Kirsher out_attach:
2171a88394cfSJeff Kirsher netif_device_attach(dev);
2172a88394cfSJeff Kirsher out:
2173a88394cfSJeff Kirsher rtnl_unlock();
2174a88394cfSJeff Kirsher return 0;
2175a88394cfSJeff Kirsher }
2176a88394cfSJeff Kirsher
21778cfa989aSVaibhav Gupta static SIMPLE_DEV_PM_OPS(de_pm_ops, de_suspend, de_resume);
2178a88394cfSJeff Kirsher
de_shutdown(struct pci_dev * pdev)2179c1181f42SMoritz Fischer static void de_shutdown(struct pci_dev *pdev)
2180c1181f42SMoritz Fischer {
2181c1181f42SMoritz Fischer struct net_device *dev = pci_get_drvdata(pdev);
2182c1181f42SMoritz Fischer
2183c1181f42SMoritz Fischer rtnl_lock();
2184c1181f42SMoritz Fischer dev_close(dev);
2185c1181f42SMoritz Fischer rtnl_unlock();
2186c1181f42SMoritz Fischer }
2187c1181f42SMoritz Fischer
2188a88394cfSJeff Kirsher static struct pci_driver de_driver = {
2189a88394cfSJeff Kirsher .name = DRV_NAME,
2190a88394cfSJeff Kirsher .id_table = de_pci_tbl,
2191a88394cfSJeff Kirsher .probe = de_init_one,
2192779c1a85SBill Pemberton .remove = de_remove_one,
2193c1181f42SMoritz Fischer .shutdown = de_shutdown,
21948cfa989aSVaibhav Gupta .driver.pm = &de_pm_ops,
2195a88394cfSJeff Kirsher };
2196a88394cfSJeff Kirsher
219702f2743eSWei Yongjun module_pci_driver(de_driver);
2198