xref: /openbmc/linux/drivers/net/ethernet/dec/tulip/dmfe.c (revision af114c42a39f7d9aa0c63081cabda9564a99a585)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2a88394cfSJeff Kirsher /*
3a88394cfSJeff Kirsher     A Davicom DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 NIC fast
4a88394cfSJeff Kirsher     ethernet driver for Linux.
5a88394cfSJeff Kirsher     Copyright (C) 1997  Sten Wang
6a88394cfSJeff Kirsher 
7a88394cfSJeff Kirsher 
8a88394cfSJeff Kirsher     DAVICOM Web-Site: www.davicom.com.tw
9a88394cfSJeff Kirsher 
10a88394cfSJeff Kirsher     Author: Sten Wang, 886-3-5798797-8517, E-mail: sten_wang@davicom.com.tw
11a88394cfSJeff Kirsher     Maintainer: Tobias Ringstrom <tori@unhappy.mine.nu>
12a88394cfSJeff Kirsher 
13a88394cfSJeff Kirsher     (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
14a88394cfSJeff Kirsher 
15a88394cfSJeff Kirsher     Marcelo Tosatti <marcelo@conectiva.com.br> :
16a88394cfSJeff Kirsher     Made it compile in 2.3 (device to net_device)
17a88394cfSJeff Kirsher 
18a88394cfSJeff Kirsher     Alan Cox <alan@lxorguk.ukuu.org.uk> :
19a88394cfSJeff Kirsher     Cleaned up for kernel merge.
20a88394cfSJeff Kirsher     Removed the back compatibility support
21a88394cfSJeff Kirsher     Reformatted, fixing spelling etc as I went
22a88394cfSJeff Kirsher     Removed IRQ 0-15 assumption
23a88394cfSJeff Kirsher 
24a88394cfSJeff Kirsher     Jeff Garzik <jgarzik@pobox.com> :
25a88394cfSJeff Kirsher     Updated to use new PCI driver API.
26a88394cfSJeff Kirsher     Resource usage cleanups.
27a88394cfSJeff Kirsher     Report driver version to user.
28a88394cfSJeff Kirsher 
29a88394cfSJeff Kirsher     Tobias Ringstrom <tori@unhappy.mine.nu> :
30a88394cfSJeff Kirsher     Cleaned up and added SMP safety.  Thanks go to Jeff Garzik,
31a88394cfSJeff Kirsher     Andrew Morton and Frank Davis for the SMP safety fixes.
32a88394cfSJeff Kirsher 
33a88394cfSJeff Kirsher     Vojtech Pavlik <vojtech@suse.cz> :
34a88394cfSJeff Kirsher     Cleaned up pointer arithmetics.
35a88394cfSJeff Kirsher     Fixed a lot of 64bit issues.
36a88394cfSJeff Kirsher     Cleaned up printk()s a bit.
37a88394cfSJeff Kirsher     Fixed some obvious big endian problems.
38a88394cfSJeff Kirsher 
39a88394cfSJeff Kirsher     Tobias Ringstrom <tori@unhappy.mine.nu> :
40a88394cfSJeff Kirsher     Use time_after for jiffies calculation.  Added ethtool
41a88394cfSJeff Kirsher     support.  Updated PCI resource allocation.  Do not
42a88394cfSJeff Kirsher     forget to unmap PCI mapped skbs.
43a88394cfSJeff Kirsher 
44a88394cfSJeff Kirsher     Alan Cox <alan@lxorguk.ukuu.org.uk>
45a88394cfSJeff Kirsher     Added new PCI identifiers provided by Clear Zhang at ALi
46a88394cfSJeff Kirsher     for their 1563 ethernet device.
47a88394cfSJeff Kirsher 
48a88394cfSJeff Kirsher     TODO
49a88394cfSJeff Kirsher 
50a88394cfSJeff Kirsher     Check on 64 bit boxes.
51a88394cfSJeff Kirsher     Check and fix on big endian boxes.
52a88394cfSJeff Kirsher 
53a88394cfSJeff Kirsher     Test and make sure PCI latency is now correct for all cases.
54a88394cfSJeff Kirsher */
55a88394cfSJeff Kirsher 
56a88394cfSJeff Kirsher #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
57a88394cfSJeff Kirsher 
58a88394cfSJeff Kirsher #define DRV_NAME	"dmfe"
59a88394cfSJeff Kirsher 
60a88394cfSJeff Kirsher #include <linux/module.h>
61a88394cfSJeff Kirsher #include <linux/kernel.h>
62a88394cfSJeff Kirsher #include <linux/string.h>
63a88394cfSJeff Kirsher #include <linux/timer.h>
64a88394cfSJeff Kirsher #include <linux/ptrace.h>
65a88394cfSJeff Kirsher #include <linux/errno.h>
66a88394cfSJeff Kirsher #include <linux/ioport.h>
67a88394cfSJeff Kirsher #include <linux/interrupt.h>
68a88394cfSJeff Kirsher #include <linux/pci.h>
69a88394cfSJeff Kirsher #include <linux/dma-mapping.h>
70a88394cfSJeff Kirsher #include <linux/init.h>
71a88394cfSJeff Kirsher #include <linux/netdevice.h>
72a88394cfSJeff Kirsher #include <linux/etherdevice.h>
73a88394cfSJeff Kirsher #include <linux/ethtool.h>
74a88394cfSJeff Kirsher #include <linux/skbuff.h>
75a88394cfSJeff Kirsher #include <linux/delay.h>
76a88394cfSJeff Kirsher #include <linux/spinlock.h>
77a88394cfSJeff Kirsher #include <linux/crc32.h>
78a88394cfSJeff Kirsher #include <linux/bitops.h>
79a88394cfSJeff Kirsher 
80a88394cfSJeff Kirsher #include <asm/processor.h>
81a88394cfSJeff Kirsher #include <asm/io.h>
82a88394cfSJeff Kirsher #include <asm/dma.h>
837c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
84a88394cfSJeff Kirsher #include <asm/irq.h>
85a88394cfSJeff Kirsher 
86a88394cfSJeff Kirsher #ifdef CONFIG_TULIP_DM910X
87a88394cfSJeff Kirsher #include <linux/of.h>
88a88394cfSJeff Kirsher #endif
89a88394cfSJeff Kirsher 
90a88394cfSJeff Kirsher 
91a88394cfSJeff Kirsher /* Board/System/Debug information/definition ---------------- */
92a88394cfSJeff Kirsher #define PCI_DM9132_ID   0x91321282      /* Davicom DM9132 ID */
93a88394cfSJeff Kirsher #define PCI_DM9102_ID   0x91021282      /* Davicom DM9102 ID */
94a88394cfSJeff Kirsher #define PCI_DM9100_ID   0x91001282      /* Davicom DM9100 ID */
95a88394cfSJeff Kirsher #define PCI_DM9009_ID   0x90091282      /* Davicom DM9009 ID */
96a88394cfSJeff Kirsher 
97a88394cfSJeff Kirsher #define DM9102_IO_SIZE  0x80
98a88394cfSJeff Kirsher #define DM9102A_IO_SIZE 0x100
99a88394cfSJeff Kirsher #define TX_MAX_SEND_CNT 0x1             /* Maximum tx packet per time */
100a88394cfSJeff Kirsher #define TX_DESC_CNT     0x10            /* Allocated Tx descriptors */
101a88394cfSJeff Kirsher #define RX_DESC_CNT     0x20            /* Allocated Rx descriptors */
102a88394cfSJeff Kirsher #define TX_FREE_DESC_CNT (TX_DESC_CNT - 2)	/* Max TX packet count */
103a88394cfSJeff Kirsher #define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3)	/* TX wakeup count */
104a88394cfSJeff Kirsher #define DESC_ALL_CNT    (TX_DESC_CNT + RX_DESC_CNT)
105a88394cfSJeff Kirsher #define TX_BUF_ALLOC    0x600
106a88394cfSJeff Kirsher #define RX_ALLOC_SIZE   0x620
107a88394cfSJeff Kirsher #define DM910X_RESET    1
108a88394cfSJeff Kirsher #define CR0_DEFAULT     0x00E00000      /* TX & RX burst mode */
109a88394cfSJeff Kirsher #define CR6_DEFAULT     0x00080000      /* HD */
110a88394cfSJeff Kirsher #define CR7_DEFAULT     0x180c1
111a88394cfSJeff Kirsher #define CR15_DEFAULT    0x06            /* TxJabber RxWatchdog */
112a88394cfSJeff Kirsher #define TDES0_ERR_MASK  0x4302          /* TXJT, LC, EC, FUE */
113a88394cfSJeff Kirsher #define MAX_PACKET_SIZE 1514
114a88394cfSJeff Kirsher #define DMFE_MAX_MULTICAST 14
115a88394cfSJeff Kirsher #define RX_COPY_SIZE	100
116a88394cfSJeff Kirsher #define MAX_CHECK_PACKET 0x8000
117a88394cfSJeff Kirsher #define DM9801_NOISE_FLOOR 8
118a88394cfSJeff Kirsher #define DM9802_NOISE_FLOOR 5
119a88394cfSJeff Kirsher 
120a88394cfSJeff Kirsher #define DMFE_WOL_LINKCHANGE	0x20000000
121a88394cfSJeff Kirsher #define DMFE_WOL_SAMPLEPACKET	0x10000000
122a88394cfSJeff Kirsher #define DMFE_WOL_MAGICPACKET	0x08000000
123a88394cfSJeff Kirsher 
124a88394cfSJeff Kirsher 
125a88394cfSJeff Kirsher #define DMFE_10MHF      0
126a88394cfSJeff Kirsher #define DMFE_100MHF     1
127a88394cfSJeff Kirsher #define DMFE_10MFD      4
128a88394cfSJeff Kirsher #define DMFE_100MFD     5
129a88394cfSJeff Kirsher #define DMFE_AUTO       8
130a88394cfSJeff Kirsher #define DMFE_1M_HPNA    0x10
131a88394cfSJeff Kirsher 
132a88394cfSJeff Kirsher #define DMFE_TXTH_72	0x400000	/* TX TH 72 byte */
133a88394cfSJeff Kirsher #define DMFE_TXTH_96	0x404000	/* TX TH 96 byte */
134a88394cfSJeff Kirsher #define DMFE_TXTH_128	0x0000		/* TX TH 128 byte */
135a88394cfSJeff Kirsher #define DMFE_TXTH_256	0x4000		/* TX TH 256 byte */
136a88394cfSJeff Kirsher #define DMFE_TXTH_512	0x8000		/* TX TH 512 byte */
137a88394cfSJeff Kirsher #define DMFE_TXTH_1K	0xC000		/* TX TH 1K  byte */
138a88394cfSJeff Kirsher 
139a88394cfSJeff Kirsher #define DMFE_TIMER_WUT  (jiffies + HZ * 1)/* timer wakeup time : 1 second */
140a88394cfSJeff Kirsher #define DMFE_TX_TIMEOUT ((3*HZ)/2)	/* tx packet time-out time 1.5 s" */
141a88394cfSJeff Kirsher #define DMFE_TX_KICK 	(HZ/2)	/* tx packet Kick-out time 0.5 s" */
142a88394cfSJeff Kirsher 
1435820e97aSFrancois Romieu #define dw32(reg, val)	iowrite32(val, ioaddr + (reg))
1445820e97aSFrancois Romieu #define dw16(reg, val)	iowrite16(val, ioaddr + (reg))
1455820e97aSFrancois Romieu #define dr32(reg)	ioread32(ioaddr + (reg))
1465820e97aSFrancois Romieu #define dr16(reg)	ioread16(ioaddr + (reg))
1475820e97aSFrancois Romieu #define dr8(reg)	ioread8(ioaddr + (reg))
1485820e97aSFrancois Romieu 
149a88394cfSJeff Kirsher #define DMFE_DBUG(dbug_now, msg, value)			\
150a88394cfSJeff Kirsher 	do {						\
151a88394cfSJeff Kirsher 		if (dmfe_debug || (dbug_now))		\
152a88394cfSJeff Kirsher 			pr_err("%s %lx\n",		\
153a88394cfSJeff Kirsher 			       (msg), (long) (value));	\
154a88394cfSJeff Kirsher 	} while (0)
155a88394cfSJeff Kirsher 
156a88394cfSJeff Kirsher #define SHOW_MEDIA_TYPE(mode)				\
157a88394cfSJeff Kirsher 	pr_info("Change Speed to %sMhz %s duplex\n" ,	\
158a88394cfSJeff Kirsher 		(mode & 1) ? "100":"10",		\
159a88394cfSJeff Kirsher 		(mode & 4) ? "full":"half");
160a88394cfSJeff Kirsher 
161a88394cfSJeff Kirsher 
162a88394cfSJeff Kirsher /* CR9 definition: SROM/MII */
163a88394cfSJeff Kirsher #define CR9_SROM_READ   0x4800
164a88394cfSJeff Kirsher #define CR9_SRCS        0x1
165a88394cfSJeff Kirsher #define CR9_SRCLK       0x2
166a88394cfSJeff Kirsher #define CR9_CRDOUT      0x8
167a88394cfSJeff Kirsher #define SROM_DATA_0     0x0
168a88394cfSJeff Kirsher #define SROM_DATA_1     0x4
169a88394cfSJeff Kirsher #define PHY_DATA_1      0x20000
170a88394cfSJeff Kirsher #define PHY_DATA_0      0x00000
171a88394cfSJeff Kirsher #define MDCLKH          0x10000
172a88394cfSJeff Kirsher 
173a88394cfSJeff Kirsher #define PHY_POWER_DOWN	0x800
174a88394cfSJeff Kirsher 
175a88394cfSJeff Kirsher #define SROM_V41_CODE   0x14
176a88394cfSJeff Kirsher 
177a88394cfSJeff Kirsher #define __CHK_IO_SIZE(pci_id, dev_rev) \
178a88394cfSJeff Kirsher  (( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x30) ) ? \
179a88394cfSJeff Kirsher 	DM9102A_IO_SIZE: DM9102_IO_SIZE)
180a88394cfSJeff Kirsher 
181a88394cfSJeff Kirsher #define CHK_IO_SIZE(pci_dev) \
182a88394cfSJeff Kirsher 	(__CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, \
183a88394cfSJeff Kirsher 	(pci_dev)->revision))
184a88394cfSJeff Kirsher 
185a88394cfSJeff Kirsher /* Structure/enum declaration ------------------------------- */
186a88394cfSJeff Kirsher struct tx_desc {
187a88394cfSJeff Kirsher         __le32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
188a88394cfSJeff Kirsher         char *tx_buf_ptr;               /* Data for us */
189a88394cfSJeff Kirsher         struct tx_desc *next_tx_desc;
190a88394cfSJeff Kirsher } __attribute__(( aligned(32) ));
191a88394cfSJeff Kirsher 
192a88394cfSJeff Kirsher struct rx_desc {
193a88394cfSJeff Kirsher 	__le32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */
194a88394cfSJeff Kirsher 	struct sk_buff *rx_skb_ptr;	/* Data for us */
195a88394cfSJeff Kirsher 	struct rx_desc *next_rx_desc;
196a88394cfSJeff Kirsher } __attribute__(( aligned(32) ));
197a88394cfSJeff Kirsher 
198a88394cfSJeff Kirsher struct dmfe_board_info {
199a88394cfSJeff Kirsher 	u32 chip_id;			/* Chip vendor/Device ID */
200a88394cfSJeff Kirsher 	u8 chip_revision;		/* Chip revision */
2015820e97aSFrancois Romieu 	struct net_device *next_dev;	/* next device */
202a88394cfSJeff Kirsher 	struct pci_dev *pdev;		/* PCI device */
203a88394cfSJeff Kirsher 	spinlock_t lock;
204a88394cfSJeff Kirsher 
2055820e97aSFrancois Romieu 	void __iomem *ioaddr;		/* I/O base address */
206a88394cfSJeff Kirsher 	u32 cr0_data;
207a88394cfSJeff Kirsher 	u32 cr5_data;
208a88394cfSJeff Kirsher 	u32 cr6_data;
209a88394cfSJeff Kirsher 	u32 cr7_data;
210a88394cfSJeff Kirsher 	u32 cr15_data;
211a88394cfSJeff Kirsher 
212a88394cfSJeff Kirsher 	/* pointer for memory physical address */
213a88394cfSJeff Kirsher 	dma_addr_t buf_pool_dma_ptr;	/* Tx buffer pool memory */
214a88394cfSJeff Kirsher 	dma_addr_t buf_pool_dma_start;	/* Tx buffer pool align dword */
215a88394cfSJeff Kirsher 	dma_addr_t desc_pool_dma_ptr;	/* descriptor pool memory */
216a88394cfSJeff Kirsher 	dma_addr_t first_tx_desc_dma;
217a88394cfSJeff Kirsher 	dma_addr_t first_rx_desc_dma;
218a88394cfSJeff Kirsher 
219a88394cfSJeff Kirsher 	/* descriptor pointer */
220a88394cfSJeff Kirsher 	unsigned char *buf_pool_ptr;	/* Tx buffer pool memory */
221a88394cfSJeff Kirsher 	unsigned char *buf_pool_start;	/* Tx buffer pool align dword */
222a88394cfSJeff Kirsher 	unsigned char *desc_pool_ptr;	/* descriptor pool memory */
223a88394cfSJeff Kirsher 	struct tx_desc *first_tx_desc;
224a88394cfSJeff Kirsher 	struct tx_desc *tx_insert_ptr;
225a88394cfSJeff Kirsher 	struct tx_desc *tx_remove_ptr;
226a88394cfSJeff Kirsher 	struct rx_desc *first_rx_desc;
227a88394cfSJeff Kirsher 	struct rx_desc *rx_insert_ptr;
228a88394cfSJeff Kirsher 	struct rx_desc *rx_ready_ptr;	/* packet come pointer */
229a88394cfSJeff Kirsher 	unsigned long tx_packet_cnt;	/* transmitted packet count */
230a88394cfSJeff Kirsher 	unsigned long tx_queue_cnt;	/* wait to send packet count */
231a88394cfSJeff Kirsher 	unsigned long rx_avail_cnt;	/* available rx descriptor count */
232a88394cfSJeff Kirsher 	unsigned long interval_rx_cnt;	/* rx packet count a callback time */
233a88394cfSJeff Kirsher 
234a88394cfSJeff Kirsher 	u16 HPNA_command;		/* For HPNA register 16 */
235a88394cfSJeff Kirsher 	u16 HPNA_timer;			/* For HPNA remote device check */
236a88394cfSJeff Kirsher 	u16 dbug_cnt;
237a88394cfSJeff Kirsher 	u16 NIC_capability;		/* NIC media capability */
238a88394cfSJeff Kirsher 	u16 PHY_reg4;			/* Saved Phyxcer register 4 value */
239a88394cfSJeff Kirsher 
240a88394cfSJeff Kirsher 	u8 HPNA_present;		/* 0:none, 1:DM9801, 2:DM9802 */
241a88394cfSJeff Kirsher 	u8 chip_type;			/* Keep DM9102A chip type */
242a88394cfSJeff Kirsher 	u8 media_mode;			/* user specify media mode */
243a88394cfSJeff Kirsher 	u8 op_mode;			/* real work media mode */
244a88394cfSJeff Kirsher 	u8 phy_addr;
245a88394cfSJeff Kirsher 	u8 wait_reset;			/* Hardware failed, need to reset */
246a88394cfSJeff Kirsher 	u8 dm910x_chk_mode;		/* Operating mode check */
247a88394cfSJeff Kirsher 	u8 first_in_callback;		/* Flag to record state */
248a88394cfSJeff Kirsher 	u8 wol_mode;			/* user WOL settings */
249a88394cfSJeff Kirsher 	struct timer_list timer;
250a88394cfSJeff Kirsher 
251a88394cfSJeff Kirsher 	/* Driver defined statistic counter */
252a88394cfSJeff Kirsher 	unsigned long tx_fifo_underrun;
253a88394cfSJeff Kirsher 	unsigned long tx_loss_carrier;
254a88394cfSJeff Kirsher 	unsigned long tx_no_carrier;
255a88394cfSJeff Kirsher 	unsigned long tx_late_collision;
256a88394cfSJeff Kirsher 	unsigned long tx_excessive_collision;
257a88394cfSJeff Kirsher 	unsigned long tx_jabber_timeout;
258a88394cfSJeff Kirsher 	unsigned long reset_count;
259a88394cfSJeff Kirsher 	unsigned long reset_cr8;
260a88394cfSJeff Kirsher 	unsigned long reset_fatal;
261a88394cfSJeff Kirsher 	unsigned long reset_TXtimeout;
262a88394cfSJeff Kirsher 
263a88394cfSJeff Kirsher 	/* NIC SROM data */
264a88394cfSJeff Kirsher 	unsigned char srom[128];
265a88394cfSJeff Kirsher };
266a88394cfSJeff Kirsher 
267a88394cfSJeff Kirsher enum dmfe_offsets {
268a88394cfSJeff Kirsher 	DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20,
269a88394cfSJeff Kirsher 	DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48,
270a88394cfSJeff Kirsher 	DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70,
271a88394cfSJeff Kirsher 	DCR15 = 0x78
272a88394cfSJeff Kirsher };
273a88394cfSJeff Kirsher 
274a88394cfSJeff Kirsher enum dmfe_CR6_bits {
275a88394cfSJeff Kirsher 	CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80,
276a88394cfSJeff Kirsher 	CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000,
277a88394cfSJeff Kirsher 	CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000
278a88394cfSJeff Kirsher };
279a88394cfSJeff Kirsher 
280a88394cfSJeff Kirsher /* Global variable declaration ----------------------------- */
281a88394cfSJeff Kirsher static int dmfe_debug;
282a88394cfSJeff Kirsher static unsigned char dmfe_media_mode = DMFE_AUTO;
283a88394cfSJeff Kirsher static u32 dmfe_cr6_user_set;
284a88394cfSJeff Kirsher 
285a88394cfSJeff Kirsher /* For module input parameter */
286a88394cfSJeff Kirsher static int debug;
287a88394cfSJeff Kirsher static u32 cr6set;
288a88394cfSJeff Kirsher static unsigned char mode = 8;
289a88394cfSJeff Kirsher static u8 chkmode = 1;
290a88394cfSJeff Kirsher static u8 HPNA_mode;		/* Default: Low Power/High Speed */
291a88394cfSJeff Kirsher static u8 HPNA_rx_cmd;		/* Default: Disable Rx remote command */
292a88394cfSJeff Kirsher static u8 HPNA_tx_cmd;		/* Default: Don't issue remote command */
293a88394cfSJeff Kirsher static u8 HPNA_NoiseFloor;	/* Default: HPNA NoiseFloor */
294a88394cfSJeff Kirsher static u8 SF_mode;		/* Special Function: 1:VLAN, 2:RX Flow Control
295a88394cfSJeff Kirsher 				   4: TX pause packet */
296a88394cfSJeff Kirsher 
297a88394cfSJeff Kirsher 
298a88394cfSJeff Kirsher /* function declaration ------------------------------------- */
299a6e5472dSFlorian Westphal static int dmfe_open(struct net_device *);
300a6e5472dSFlorian Westphal static netdev_tx_t dmfe_start_xmit(struct sk_buff *, struct net_device *);
301a6e5472dSFlorian Westphal static int dmfe_stop(struct net_device *);
302a6e5472dSFlorian Westphal static void dmfe_set_filter_mode(struct net_device *);
303a88394cfSJeff Kirsher static const struct ethtool_ops netdev_ethtool_ops;
3045820e97aSFrancois Romieu static u16 read_srom_word(void __iomem *, int);
305a88394cfSJeff Kirsher static irqreturn_t dmfe_interrupt(int , void *);
306a88394cfSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
307a88394cfSJeff Kirsher static void poll_dmfe (struct net_device *dev);
308a88394cfSJeff Kirsher #endif
3095820e97aSFrancois Romieu static void dmfe_descriptor_init(struct net_device *);
3101ab0d2ecSPradeep A. Dalvi static void allocate_rx_buffer(struct net_device *);
3115820e97aSFrancois Romieu static void update_cr6(u32, void __iomem *);
312a6e5472dSFlorian Westphal static void send_filter_frame(struct net_device *);
313a6e5472dSFlorian Westphal static void dm9132_id_table(struct net_device *);
31473852b2bSDavid S. Miller static u16 dmfe_phy_read(void __iomem *, u8, u8, u32);
31573852b2bSDavid S. Miller static void dmfe_phy_write(void __iomem *, u8, u8, u16, u32);
31673852b2bSDavid S. Miller static void dmfe_phy_write_1bit(void __iomem *, u32);
31773852b2bSDavid S. Miller static u16 dmfe_phy_read_1bit(void __iomem *);
318a88394cfSJeff Kirsher static u8 dmfe_sense_speed(struct dmfe_board_info *);
319a88394cfSJeff Kirsher static void dmfe_process_mode(struct dmfe_board_info *);
320a8c22a2bSKees Cook static void dmfe_timer(struct timer_list *);
321a88394cfSJeff Kirsher static inline u32 cal_CRC(unsigned char *, unsigned int, u8);
322a6e5472dSFlorian Westphal static void dmfe_rx_packet(struct net_device *, struct dmfe_board_info *);
323a6e5472dSFlorian Westphal static void dmfe_free_tx_pkt(struct net_device *, struct dmfe_board_info *);
324a88394cfSJeff Kirsher static void dmfe_reuse_skb(struct dmfe_board_info *, struct sk_buff *);
325a6e5472dSFlorian Westphal static void dmfe_dynamic_reset(struct net_device *);
326a88394cfSJeff Kirsher static void dmfe_free_rxbuffer(struct dmfe_board_info *);
327a6e5472dSFlorian Westphal static void dmfe_init_dm910x(struct net_device *);
328a88394cfSJeff Kirsher static void dmfe_parse_srom(struct dmfe_board_info *);
329a88394cfSJeff Kirsher static void dmfe_program_DM9801(struct dmfe_board_info *, int);
330a88394cfSJeff Kirsher static void dmfe_program_DM9802(struct dmfe_board_info *);
331a88394cfSJeff Kirsher static void dmfe_HPNA_remote_cmd_chk(struct dmfe_board_info * );
332a88394cfSJeff Kirsher static void dmfe_set_phyxcer(struct dmfe_board_info *);
333a88394cfSJeff Kirsher 
334a88394cfSJeff Kirsher /* DM910X network board routine ---------------------------- */
335a88394cfSJeff Kirsher 
336a88394cfSJeff Kirsher static const struct net_device_ops netdev_ops = {
337a88394cfSJeff Kirsher 	.ndo_open 		= dmfe_open,
338a88394cfSJeff Kirsher 	.ndo_stop		= dmfe_stop,
339a88394cfSJeff Kirsher 	.ndo_start_xmit		= dmfe_start_xmit,
340afc4b13dSJiri Pirko 	.ndo_set_rx_mode	= dmfe_set_filter_mode,
341a88394cfSJeff Kirsher 	.ndo_set_mac_address	= eth_mac_addr,
342a88394cfSJeff Kirsher 	.ndo_validate_addr	= eth_validate_addr,
343a88394cfSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
344a88394cfSJeff Kirsher 	.ndo_poll_controller	= poll_dmfe,
345a88394cfSJeff Kirsher #endif
346a88394cfSJeff Kirsher };
347a88394cfSJeff Kirsher 
348a88394cfSJeff Kirsher /*
349a88394cfSJeff Kirsher  *	Search DM910X board ,allocate space and register it
350a88394cfSJeff Kirsher  */
351a88394cfSJeff Kirsher 
3521dd06ae8SGreg Kroah-Hartman static int dmfe_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
353a88394cfSJeff Kirsher {
354a88394cfSJeff Kirsher 	struct dmfe_board_info *db;	/* board information structure */
355a88394cfSJeff Kirsher 	struct net_device *dev;
356a88394cfSJeff Kirsher 	u32 pci_pmr;
357a88394cfSJeff Kirsher 	int i, err;
358a88394cfSJeff Kirsher 
359a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_init_one()", 0);
360a88394cfSJeff Kirsher 
361a88394cfSJeff Kirsher 	/*
362a88394cfSJeff Kirsher 	 *	SPARC on-board DM910x chips should be handled by the main
363a88394cfSJeff Kirsher 	 *	tulip driver, except for early DM9100s.
364a88394cfSJeff Kirsher 	 */
365a88394cfSJeff Kirsher #ifdef CONFIG_TULIP_DM910X
366a88394cfSJeff Kirsher 	if ((ent->driver_data == PCI_DM9100_ID && pdev->revision >= 0x30) ||
367a88394cfSJeff Kirsher 	    ent->driver_data == PCI_DM9102_ID) {
368a88394cfSJeff Kirsher 		struct device_node *dp = pci_device_to_OF_node(pdev);
369a88394cfSJeff Kirsher 
370a88394cfSJeff Kirsher 		if (dp && of_get_property(dp, "local-mac-address", NULL)) {
371a88394cfSJeff Kirsher 			pr_info("skipping on-board DM910x (use tulip)\n");
372a88394cfSJeff Kirsher 			return -ENODEV;
373a88394cfSJeff Kirsher 		}
374a88394cfSJeff Kirsher 	}
375a88394cfSJeff Kirsher #endif
376a88394cfSJeff Kirsher 
377a88394cfSJeff Kirsher 	/* Init network device */
378a88394cfSJeff Kirsher 	dev = alloc_etherdev(sizeof(*db));
379a88394cfSJeff Kirsher 	if (dev == NULL)
380a88394cfSJeff Kirsher 		return -ENOMEM;
381a88394cfSJeff Kirsher 	SET_NETDEV_DEV(dev, &pdev->dev);
382a88394cfSJeff Kirsher 
383*af114c42SChristophe JAILLET 	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
384a88394cfSJeff Kirsher 		pr_warn("32-bit PCI DMA not available\n");
385a88394cfSJeff Kirsher 		err = -ENODEV;
386a88394cfSJeff Kirsher 		goto err_out_free;
387a88394cfSJeff Kirsher 	}
388a88394cfSJeff Kirsher 
389a88394cfSJeff Kirsher 	/* Enable Master/IO access, Disable memory access */
390a88394cfSJeff Kirsher 	err = pci_enable_device(pdev);
391a88394cfSJeff Kirsher 	if (err)
392a88394cfSJeff Kirsher 		goto err_out_free;
393a88394cfSJeff Kirsher 
394a88394cfSJeff Kirsher 	if (!pci_resource_start(pdev, 0)) {
395a88394cfSJeff Kirsher 		pr_err("I/O base is zero\n");
396a88394cfSJeff Kirsher 		err = -ENODEV;
397a88394cfSJeff Kirsher 		goto err_out_disable;
398a88394cfSJeff Kirsher 	}
399a88394cfSJeff Kirsher 
400a88394cfSJeff Kirsher 	if (pci_resource_len(pdev, 0) < (CHK_IO_SIZE(pdev)) ) {
401a88394cfSJeff Kirsher 		pr_err("Allocated I/O size too small\n");
402a88394cfSJeff Kirsher 		err = -ENODEV;
403a88394cfSJeff Kirsher 		goto err_out_disable;
404a88394cfSJeff Kirsher 	}
405a88394cfSJeff Kirsher 
406a88394cfSJeff Kirsher #if 0	/* pci_{enable_device,set_master} sets minimum latency for us now */
407a88394cfSJeff Kirsher 
408a88394cfSJeff Kirsher 	/* Set Latency Timer 80h */
409a88394cfSJeff Kirsher 	/* FIXME: setting values > 32 breaks some SiS 559x stuff.
410a88394cfSJeff Kirsher 	   Need a PCI quirk.. */
411a88394cfSJeff Kirsher 
412a88394cfSJeff Kirsher 	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);
413a88394cfSJeff Kirsher #endif
414a88394cfSJeff Kirsher 
415a88394cfSJeff Kirsher 	if (pci_request_regions(pdev, DRV_NAME)) {
416a88394cfSJeff Kirsher 		pr_err("Failed to request PCI regions\n");
417a88394cfSJeff Kirsher 		err = -ENODEV;
418a88394cfSJeff Kirsher 		goto err_out_disable;
419a88394cfSJeff Kirsher 	}
420a88394cfSJeff Kirsher 
421a88394cfSJeff Kirsher 	/* Init system & device */
422a88394cfSJeff Kirsher 	db = netdev_priv(dev);
423a88394cfSJeff Kirsher 
424a88394cfSJeff Kirsher 	/* Allocate Tx/Rx descriptor memory */
425*af114c42SChristophe JAILLET 	db->desc_pool_ptr = dma_alloc_coherent(&pdev->dev,
426*af114c42SChristophe JAILLET 					       sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
427*af114c42SChristophe JAILLET 					       &db->desc_pool_dma_ptr, GFP_KERNEL);
4285b896029SPeter Senna Tschudin 	if (!db->desc_pool_ptr) {
4295b896029SPeter Senna Tschudin 		err = -ENOMEM;
430a88394cfSJeff Kirsher 		goto err_out_res;
4315b896029SPeter Senna Tschudin 	}
432a88394cfSJeff Kirsher 
433*af114c42SChristophe JAILLET 	db->buf_pool_ptr = dma_alloc_coherent(&pdev->dev,
434*af114c42SChristophe JAILLET 					      TX_BUF_ALLOC * TX_DESC_CNT + 4,
435*af114c42SChristophe JAILLET 					      &db->buf_pool_dma_ptr, GFP_KERNEL);
4365b896029SPeter Senna Tschudin 	if (!db->buf_pool_ptr) {
4375b896029SPeter Senna Tschudin 		err = -ENOMEM;
438a88394cfSJeff Kirsher 		goto err_out_free_desc;
4395b896029SPeter Senna Tschudin 	}
440a88394cfSJeff Kirsher 
441a88394cfSJeff Kirsher 	db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
442a88394cfSJeff Kirsher 	db->first_tx_desc_dma = db->desc_pool_dma_ptr;
443a88394cfSJeff Kirsher 	db->buf_pool_start = db->buf_pool_ptr;
444a88394cfSJeff Kirsher 	db->buf_pool_dma_start = db->buf_pool_dma_ptr;
445a88394cfSJeff Kirsher 
446a88394cfSJeff Kirsher 	db->chip_id = ent->driver_data;
4475820e97aSFrancois Romieu 	/* IO type range. */
4485820e97aSFrancois Romieu 	db->ioaddr = pci_iomap(pdev, 0, 0);
4495b896029SPeter Senna Tschudin 	if (!db->ioaddr) {
4505b896029SPeter Senna Tschudin 		err = -ENOMEM;
4515820e97aSFrancois Romieu 		goto err_out_free_buf;
4525b896029SPeter Senna Tschudin 	}
4535820e97aSFrancois Romieu 
454a88394cfSJeff Kirsher 	db->chip_revision = pdev->revision;
455a88394cfSJeff Kirsher 	db->wol_mode = 0;
456a88394cfSJeff Kirsher 
457a88394cfSJeff Kirsher 	db->pdev = pdev;
458a88394cfSJeff Kirsher 
459a88394cfSJeff Kirsher 	pci_set_drvdata(pdev, dev);
460a88394cfSJeff Kirsher 	dev->netdev_ops = &netdev_ops;
461a88394cfSJeff Kirsher 	dev->ethtool_ops = &netdev_ethtool_ops;
462a88394cfSJeff Kirsher 	netif_carrier_off(dev);
463a88394cfSJeff Kirsher 	spin_lock_init(&db->lock);
464a88394cfSJeff Kirsher 
465a88394cfSJeff Kirsher 	pci_read_config_dword(pdev, 0x50, &pci_pmr);
466a88394cfSJeff Kirsher 	pci_pmr &= 0x70000;
467a88394cfSJeff Kirsher 	if ( (pci_pmr == 0x10000) && (db->chip_revision == 0x31) )
468a88394cfSJeff Kirsher 		db->chip_type = 1;	/* DM9102A E3 */
469a88394cfSJeff Kirsher 	else
470a88394cfSJeff Kirsher 		db->chip_type = 0;
471a88394cfSJeff Kirsher 
472a88394cfSJeff Kirsher 	/* read 64 word srom data */
4735820e97aSFrancois Romieu 	for (i = 0; i < 64; i++) {
474a88394cfSJeff Kirsher 		((__le16 *) db->srom)[i] =
475a88394cfSJeff Kirsher 			cpu_to_le16(read_srom_word(db->ioaddr, i));
4765820e97aSFrancois Romieu 	}
477a88394cfSJeff Kirsher 
478a88394cfSJeff Kirsher 	/* Set Node address */
479a88394cfSJeff Kirsher 	for (i = 0; i < 6; i++)
480a88394cfSJeff Kirsher 		dev->dev_addr[i] = db->srom[20 + i];
481a88394cfSJeff Kirsher 
482a88394cfSJeff Kirsher 	err = register_netdev (dev);
483a88394cfSJeff Kirsher 	if (err)
4845820e97aSFrancois Romieu 		goto err_out_unmap;
485a88394cfSJeff Kirsher 
486a88394cfSJeff Kirsher 	dev_info(&dev->dev, "Davicom DM%04lx at pci%s, %pM, irq %d\n",
487a88394cfSJeff Kirsher 		 ent->driver_data >> 16,
4885820e97aSFrancois Romieu 		 pci_name(pdev), dev->dev_addr, pdev->irq);
489a88394cfSJeff Kirsher 
490a88394cfSJeff Kirsher 	pci_set_master(pdev);
491a88394cfSJeff Kirsher 
492a88394cfSJeff Kirsher 	return 0;
493a88394cfSJeff Kirsher 
4945820e97aSFrancois Romieu err_out_unmap:
4955820e97aSFrancois Romieu 	pci_iounmap(pdev, db->ioaddr);
496a88394cfSJeff Kirsher err_out_free_buf:
497*af114c42SChristophe JAILLET 	dma_free_coherent(&pdev->dev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
498a88394cfSJeff Kirsher 			  db->buf_pool_ptr, db->buf_pool_dma_ptr);
499a88394cfSJeff Kirsher err_out_free_desc:
500*af114c42SChristophe JAILLET 	dma_free_coherent(&pdev->dev,
501*af114c42SChristophe JAILLET 			  sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
502a88394cfSJeff Kirsher 			  db->desc_pool_ptr, db->desc_pool_dma_ptr);
503a88394cfSJeff Kirsher err_out_res:
504a88394cfSJeff Kirsher 	pci_release_regions(pdev);
505a88394cfSJeff Kirsher err_out_disable:
506a88394cfSJeff Kirsher 	pci_disable_device(pdev);
507a88394cfSJeff Kirsher err_out_free:
508a88394cfSJeff Kirsher 	free_netdev(dev);
509a88394cfSJeff Kirsher 
510a88394cfSJeff Kirsher 	return err;
511a88394cfSJeff Kirsher }
512a88394cfSJeff Kirsher 
513a88394cfSJeff Kirsher 
514779c1a85SBill Pemberton static void dmfe_remove_one(struct pci_dev *pdev)
515a88394cfSJeff Kirsher {
516a88394cfSJeff Kirsher 	struct net_device *dev = pci_get_drvdata(pdev);
517a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
518a88394cfSJeff Kirsher 
519a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_remove_one()", 0);
520a88394cfSJeff Kirsher 
521a88394cfSJeff Kirsher  	if (dev) {
522a88394cfSJeff Kirsher 
523a88394cfSJeff Kirsher 		unregister_netdev(dev);
5245820e97aSFrancois Romieu 		pci_iounmap(db->pdev, db->ioaddr);
525*af114c42SChristophe JAILLET 		dma_free_coherent(&db->pdev->dev,
526*af114c42SChristophe JAILLET 				  sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
527*af114c42SChristophe JAILLET 				  db->desc_pool_ptr, db->desc_pool_dma_ptr);
528*af114c42SChristophe JAILLET 		dma_free_coherent(&db->pdev->dev,
529*af114c42SChristophe JAILLET 				  TX_BUF_ALLOC * TX_DESC_CNT + 4,
530a88394cfSJeff Kirsher 				  db->buf_pool_ptr, db->buf_pool_dma_ptr);
531a88394cfSJeff Kirsher 		pci_release_regions(pdev);
532a88394cfSJeff Kirsher 		free_netdev(dev);	/* free board information */
533a88394cfSJeff Kirsher 	}
534a88394cfSJeff Kirsher 
535a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_remove_one() exit", 0);
536a88394cfSJeff Kirsher }
537a88394cfSJeff Kirsher 
538a88394cfSJeff Kirsher 
539a88394cfSJeff Kirsher /*
540a88394cfSJeff Kirsher  *	Open the interface.
541a88394cfSJeff Kirsher  *	The interface is opened whenever "ifconfig" actives it.
542a88394cfSJeff Kirsher  */
543a88394cfSJeff Kirsher 
544a6e5472dSFlorian Westphal static int dmfe_open(struct net_device *dev)
545a88394cfSJeff Kirsher {
546a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
5475820e97aSFrancois Romieu 	const int irq = db->pdev->irq;
5485820e97aSFrancois Romieu 	int ret;
549a88394cfSJeff Kirsher 
550a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_open", 0);
551a88394cfSJeff Kirsher 
5525820e97aSFrancois Romieu 	ret = request_irq(irq, dmfe_interrupt, IRQF_SHARED, dev->name, dev);
553a88394cfSJeff Kirsher 	if (ret)
554a88394cfSJeff Kirsher 		return ret;
555a88394cfSJeff Kirsher 
556a88394cfSJeff Kirsher 	/* system variable init */
557a88394cfSJeff Kirsher 	db->cr6_data = CR6_DEFAULT | dmfe_cr6_user_set;
558a88394cfSJeff Kirsher 	db->tx_packet_cnt = 0;
559a88394cfSJeff Kirsher 	db->tx_queue_cnt = 0;
560a88394cfSJeff Kirsher 	db->rx_avail_cnt = 0;
561a88394cfSJeff Kirsher 	db->wait_reset = 0;
562a88394cfSJeff Kirsher 
563a88394cfSJeff Kirsher 	db->first_in_callback = 0;
564a88394cfSJeff Kirsher 	db->NIC_capability = 0xf;	/* All capability*/
565a88394cfSJeff Kirsher 	db->PHY_reg4 = 0x1e0;
566a88394cfSJeff Kirsher 
567a88394cfSJeff Kirsher 	/* CR6 operation mode decision */
568a88394cfSJeff Kirsher 	if ( !chkmode || (db->chip_id == PCI_DM9132_ID) ||
569a88394cfSJeff Kirsher 		(db->chip_revision >= 0x30) ) {
570a88394cfSJeff Kirsher     		db->cr6_data |= DMFE_TXTH_256;
571a88394cfSJeff Kirsher 		db->cr0_data = CR0_DEFAULT;
572a88394cfSJeff Kirsher 		db->dm910x_chk_mode=4;		/* Enter the normal mode */
573a88394cfSJeff Kirsher  	} else {
574a88394cfSJeff Kirsher 		db->cr6_data |= CR6_SFT;	/* Store & Forward mode */
575a88394cfSJeff Kirsher 		db->cr0_data = 0;
576a88394cfSJeff Kirsher 		db->dm910x_chk_mode = 1;	/* Enter the check mode */
577a88394cfSJeff Kirsher 	}
578a88394cfSJeff Kirsher 
579a88394cfSJeff Kirsher 	/* Initialize DM910X board */
580a88394cfSJeff Kirsher 	dmfe_init_dm910x(dev);
581a88394cfSJeff Kirsher 
582a88394cfSJeff Kirsher 	/* Active System Interface */
583a88394cfSJeff Kirsher 	netif_wake_queue(dev);
584a88394cfSJeff Kirsher 
585a88394cfSJeff Kirsher 	/* set and active a timer process */
586a8c22a2bSKees Cook 	timer_setup(&db->timer, dmfe_timer, 0);
587a88394cfSJeff Kirsher 	db->timer.expires = DMFE_TIMER_WUT + HZ * 2;
588a88394cfSJeff Kirsher 	add_timer(&db->timer);
589a88394cfSJeff Kirsher 
590a88394cfSJeff Kirsher 	return 0;
591a88394cfSJeff Kirsher }
592a88394cfSJeff Kirsher 
593a88394cfSJeff Kirsher 
594a88394cfSJeff Kirsher /*	Initialize DM910X board
595a88394cfSJeff Kirsher  *	Reset DM910X board
596a88394cfSJeff Kirsher  *	Initialize TX/Rx descriptor chain structure
597a88394cfSJeff Kirsher  *	Send the set-up frame
598a88394cfSJeff Kirsher  *	Enable Tx/Rx machine
599a88394cfSJeff Kirsher  */
600a88394cfSJeff Kirsher 
601a6e5472dSFlorian Westphal static void dmfe_init_dm910x(struct net_device *dev)
602a88394cfSJeff Kirsher {
603a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
6045820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
605a88394cfSJeff Kirsher 
606a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_init_dm910x()", 0);
607a88394cfSJeff Kirsher 
608a88394cfSJeff Kirsher 	/* Reset DM910x MAC controller */
6095820e97aSFrancois Romieu 	dw32(DCR0, DM910X_RESET);	/* RESET MAC */
610a88394cfSJeff Kirsher 	udelay(100);
6115820e97aSFrancois Romieu 	dw32(DCR0, db->cr0_data);
612a88394cfSJeff Kirsher 	udelay(5);
613a88394cfSJeff Kirsher 
614a88394cfSJeff Kirsher 	/* Phy addr : DM910(A)2/DM9132/9801, phy address = 1 */
615a88394cfSJeff Kirsher 	db->phy_addr = 1;
616a88394cfSJeff Kirsher 
617a88394cfSJeff Kirsher 	/* Parser SROM and media mode */
618a88394cfSJeff Kirsher 	dmfe_parse_srom(db);
619a88394cfSJeff Kirsher 	db->media_mode = dmfe_media_mode;
620a88394cfSJeff Kirsher 
621a88394cfSJeff Kirsher 	/* RESET Phyxcer Chip by GPR port bit 7 */
6225820e97aSFrancois Romieu 	dw32(DCR12, 0x180);		/* Let bit 7 output port */
623a88394cfSJeff Kirsher 	if (db->chip_id == PCI_DM9009_ID) {
6245820e97aSFrancois Romieu 		dw32(DCR12, 0x80);	/* Issue RESET signal */
625a88394cfSJeff Kirsher 		mdelay(300);			/* Delay 300 ms */
626a88394cfSJeff Kirsher 	}
6275820e97aSFrancois Romieu 	dw32(DCR12, 0x0);	/* Clear RESET signal */
628a88394cfSJeff Kirsher 
629a88394cfSJeff Kirsher 	/* Process Phyxcer Media Mode */
630a88394cfSJeff Kirsher 	if ( !(db->media_mode & 0x10) )	/* Force 1M mode */
631a88394cfSJeff Kirsher 		dmfe_set_phyxcer(db);
632a88394cfSJeff Kirsher 
633a88394cfSJeff Kirsher 	/* Media Mode Process */
634a88394cfSJeff Kirsher 	if ( !(db->media_mode & DMFE_AUTO) )
635a88394cfSJeff Kirsher 		db->op_mode = db->media_mode; 	/* Force Mode */
636a88394cfSJeff Kirsher 
637dbedd44eSJoe Perches 	/* Initialize Transmit/Receive descriptor and CR3/4 */
6385820e97aSFrancois Romieu 	dmfe_descriptor_init(dev);
639a88394cfSJeff Kirsher 
640a88394cfSJeff Kirsher 	/* Init CR6 to program DM910x operation */
641a88394cfSJeff Kirsher 	update_cr6(db->cr6_data, ioaddr);
642a88394cfSJeff Kirsher 
643a88394cfSJeff Kirsher 	/* Send setup frame */
644a88394cfSJeff Kirsher 	if (db->chip_id == PCI_DM9132_ID)
645a88394cfSJeff Kirsher 		dm9132_id_table(dev);	/* DM9132 */
646a88394cfSJeff Kirsher 	else
647a88394cfSJeff Kirsher 		send_filter_frame(dev);	/* DM9102/DM9102A */
648a88394cfSJeff Kirsher 
649a88394cfSJeff Kirsher 	/* Init CR7, interrupt active bit */
650a88394cfSJeff Kirsher 	db->cr7_data = CR7_DEFAULT;
6515820e97aSFrancois Romieu 	dw32(DCR7, db->cr7_data);
652a88394cfSJeff Kirsher 
653a88394cfSJeff Kirsher 	/* Init CR15, Tx jabber and Rx watchdog timer */
6545820e97aSFrancois Romieu 	dw32(DCR15, db->cr15_data);
655a88394cfSJeff Kirsher 
656a88394cfSJeff Kirsher 	/* Enable DM910X Tx/Rx function */
657a88394cfSJeff Kirsher 	db->cr6_data |= CR6_RXSC | CR6_TXSC | 0x40000;
658a88394cfSJeff Kirsher 	update_cr6(db->cr6_data, ioaddr);
659a88394cfSJeff Kirsher }
660a88394cfSJeff Kirsher 
661a88394cfSJeff Kirsher 
662a88394cfSJeff Kirsher /*
663a88394cfSJeff Kirsher  *	Hardware start transmission.
664a88394cfSJeff Kirsher  *	Send a packet to media from the upper layer.
665a88394cfSJeff Kirsher  */
666a88394cfSJeff Kirsher 
667a88394cfSJeff Kirsher static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
668a6e5472dSFlorian Westphal 					 struct net_device *dev)
669a88394cfSJeff Kirsher {
670a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
6715820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
672a88394cfSJeff Kirsher 	struct tx_desc *txptr;
673a88394cfSJeff Kirsher 	unsigned long flags;
674a88394cfSJeff Kirsher 
675a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_start_xmit", 0);
676a88394cfSJeff Kirsher 
677a88394cfSJeff Kirsher 	/* Too large packet check */
678a88394cfSJeff Kirsher 	if (skb->len > MAX_PACKET_SIZE) {
679a88394cfSJeff Kirsher 		pr_err("big packet = %d\n", (u16)skb->len);
680086dfb7fSEric W. Biederman 		dev_kfree_skb_any(skb);
681a88394cfSJeff Kirsher 		return NETDEV_TX_OK;
682a88394cfSJeff Kirsher 	}
683a88394cfSJeff Kirsher 
684a88394cfSJeff Kirsher 	/* Resource flag check */
685a88394cfSJeff Kirsher 	netif_stop_queue(dev);
686a88394cfSJeff Kirsher 
687a88394cfSJeff Kirsher 	spin_lock_irqsave(&db->lock, flags);
688a88394cfSJeff Kirsher 
689a88394cfSJeff Kirsher 	/* No Tx resource check, it never happen nromally */
690a88394cfSJeff Kirsher 	if (db->tx_queue_cnt >= TX_FREE_DESC_CNT) {
691a88394cfSJeff Kirsher 		spin_unlock_irqrestore(&db->lock, flags);
692a88394cfSJeff Kirsher 		pr_err("No Tx resource %ld\n", db->tx_queue_cnt);
693a88394cfSJeff Kirsher 		return NETDEV_TX_BUSY;
694a88394cfSJeff Kirsher 	}
695a88394cfSJeff Kirsher 
696a88394cfSJeff Kirsher 	/* Disable NIC interrupt */
6975820e97aSFrancois Romieu 	dw32(DCR7, 0);
698a88394cfSJeff Kirsher 
699a88394cfSJeff Kirsher 	/* transmit this packet */
700a88394cfSJeff Kirsher 	txptr = db->tx_insert_ptr;
701a88394cfSJeff Kirsher 	skb_copy_from_linear_data(skb, txptr->tx_buf_ptr, skb->len);
702a88394cfSJeff Kirsher 	txptr->tdes1 = cpu_to_le32(0xe1000000 | skb->len);
703a88394cfSJeff Kirsher 
704a88394cfSJeff Kirsher 	/* Point to next transmit free descriptor */
705a88394cfSJeff Kirsher 	db->tx_insert_ptr = txptr->next_tx_desc;
706a88394cfSJeff Kirsher 
707a88394cfSJeff Kirsher 	/* Transmit Packet Process */
708a88394cfSJeff Kirsher 	if ( (!db->tx_queue_cnt) && (db->tx_packet_cnt < TX_MAX_SEND_CNT) ) {
709a88394cfSJeff Kirsher 		txptr->tdes0 = cpu_to_le32(0x80000000);	/* Set owner bit */
710a88394cfSJeff Kirsher 		db->tx_packet_cnt++;			/* Ready to send */
7115820e97aSFrancois Romieu 		dw32(DCR1, 0x1);			/* Issue Tx polling */
712860e9538SFlorian Westphal 		netif_trans_update(dev);		/* saved time stamp */
713a88394cfSJeff Kirsher 	} else {
714a88394cfSJeff Kirsher 		db->tx_queue_cnt++;			/* queue TX packet */
7155820e97aSFrancois Romieu 		dw32(DCR1, 0x1);			/* Issue Tx polling */
716a88394cfSJeff Kirsher 	}
717a88394cfSJeff Kirsher 
718a88394cfSJeff Kirsher 	/* Tx resource check */
719a88394cfSJeff Kirsher 	if ( db->tx_queue_cnt < TX_FREE_DESC_CNT )
720a88394cfSJeff Kirsher 		netif_wake_queue(dev);
721a88394cfSJeff Kirsher 
722a88394cfSJeff Kirsher 	/* Restore CR7 to enable interrupt */
723a88394cfSJeff Kirsher 	spin_unlock_irqrestore(&db->lock, flags);
7245820e97aSFrancois Romieu 	dw32(DCR7, db->cr7_data);
725a88394cfSJeff Kirsher 
726a88394cfSJeff Kirsher 	/* free this SKB */
727086dfb7fSEric W. Biederman 	dev_consume_skb_any(skb);
728a88394cfSJeff Kirsher 
729a88394cfSJeff Kirsher 	return NETDEV_TX_OK;
730a88394cfSJeff Kirsher }
731a88394cfSJeff Kirsher 
732a88394cfSJeff Kirsher 
733a88394cfSJeff Kirsher /*
734a88394cfSJeff Kirsher  *	Stop the interface.
735a88394cfSJeff Kirsher  *	The interface is stopped when it is brought.
736a88394cfSJeff Kirsher  */
737a88394cfSJeff Kirsher 
738a6e5472dSFlorian Westphal static int dmfe_stop(struct net_device *dev)
739a88394cfSJeff Kirsher {
740a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
7415820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
742a88394cfSJeff Kirsher 
743a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_stop", 0);
744a88394cfSJeff Kirsher 
745a88394cfSJeff Kirsher 	/* disable system */
746a88394cfSJeff Kirsher 	netif_stop_queue(dev);
747a88394cfSJeff Kirsher 
748a88394cfSJeff Kirsher 	/* deleted timer */
749a88394cfSJeff Kirsher 	del_timer_sync(&db->timer);
750a88394cfSJeff Kirsher 
751a88394cfSJeff Kirsher 	/* Reset & stop DM910X board */
7525820e97aSFrancois Romieu 	dw32(DCR0, DM910X_RESET);
7530c204940Sfrançois romieu 	udelay(100);
75473852b2bSDavid S. Miller 	dmfe_phy_write(ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
755a88394cfSJeff Kirsher 
756a88394cfSJeff Kirsher 	/* free interrupt */
7575820e97aSFrancois Romieu 	free_irq(db->pdev->irq, dev);
758a88394cfSJeff Kirsher 
759a88394cfSJeff Kirsher 	/* free allocated rx buffer */
760a88394cfSJeff Kirsher 	dmfe_free_rxbuffer(db);
761a88394cfSJeff Kirsher 
762a88394cfSJeff Kirsher #if 0
763a88394cfSJeff Kirsher 	/* show statistic counter */
764a88394cfSJeff Kirsher 	printk("FU:%lx EC:%lx LC:%lx NC:%lx LOC:%lx TXJT:%lx RESET:%lx RCR8:%lx FAL:%lx TT:%lx\n",
765a88394cfSJeff Kirsher 	       db->tx_fifo_underrun, db->tx_excessive_collision,
766a88394cfSJeff Kirsher 	       db->tx_late_collision, db->tx_no_carrier, db->tx_loss_carrier,
767a88394cfSJeff Kirsher 	       db->tx_jabber_timeout, db->reset_count, db->reset_cr8,
768a88394cfSJeff Kirsher 	       db->reset_fatal, db->reset_TXtimeout);
769a88394cfSJeff Kirsher #endif
770a88394cfSJeff Kirsher 
771a88394cfSJeff Kirsher 	return 0;
772a88394cfSJeff Kirsher }
773a88394cfSJeff Kirsher 
774a88394cfSJeff Kirsher 
775a88394cfSJeff Kirsher /*
776a88394cfSJeff Kirsher  *	DM9102 insterrupt handler
777a88394cfSJeff Kirsher  *	receive the packet to upper layer, free the transmitted packet
778a88394cfSJeff Kirsher  */
779a88394cfSJeff Kirsher 
780a88394cfSJeff Kirsher static irqreturn_t dmfe_interrupt(int irq, void *dev_id)
781a88394cfSJeff Kirsher {
782a6e5472dSFlorian Westphal 	struct net_device *dev = dev_id;
783a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
7845820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
785a88394cfSJeff Kirsher 	unsigned long flags;
786a88394cfSJeff Kirsher 
787a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_interrupt()", 0);
788a88394cfSJeff Kirsher 
789a88394cfSJeff Kirsher 	spin_lock_irqsave(&db->lock, flags);
790a88394cfSJeff Kirsher 
791a88394cfSJeff Kirsher 	/* Got DM910X status */
7925820e97aSFrancois Romieu 	db->cr5_data = dr32(DCR5);
7935820e97aSFrancois Romieu 	dw32(DCR5, db->cr5_data);
794a88394cfSJeff Kirsher 	if ( !(db->cr5_data & 0xc1) ) {
795a88394cfSJeff Kirsher 		spin_unlock_irqrestore(&db->lock, flags);
796a88394cfSJeff Kirsher 		return IRQ_HANDLED;
797a88394cfSJeff Kirsher 	}
798a88394cfSJeff Kirsher 
799a88394cfSJeff Kirsher 	/* Disable all interrupt in CR7 to solve the interrupt edge problem */
8005820e97aSFrancois Romieu 	dw32(DCR7, 0);
801a88394cfSJeff Kirsher 
802a88394cfSJeff Kirsher 	/* Check system status */
803a88394cfSJeff Kirsher 	if (db->cr5_data & 0x2000) {
804a88394cfSJeff Kirsher 		/* system bus error happen */
805a88394cfSJeff Kirsher 		DMFE_DBUG(1, "System bus error happen. CR5=", db->cr5_data);
806a88394cfSJeff Kirsher 		db->reset_fatal++;
807a88394cfSJeff Kirsher 		db->wait_reset = 1;	/* Need to RESET */
808a88394cfSJeff Kirsher 		spin_unlock_irqrestore(&db->lock, flags);
809a88394cfSJeff Kirsher 		return IRQ_HANDLED;
810a88394cfSJeff Kirsher 	}
811a88394cfSJeff Kirsher 
812a88394cfSJeff Kirsher 	 /* Received the coming packet */
813a88394cfSJeff Kirsher 	if ( (db->cr5_data & 0x40) && db->rx_avail_cnt )
814a88394cfSJeff Kirsher 		dmfe_rx_packet(dev, db);
815a88394cfSJeff Kirsher 
816a88394cfSJeff Kirsher 	/* reallocate rx descriptor buffer */
817a88394cfSJeff Kirsher 	if (db->rx_avail_cnt<RX_DESC_CNT)
8181ab0d2ecSPradeep A. Dalvi 		allocate_rx_buffer(dev);
819a88394cfSJeff Kirsher 
820a88394cfSJeff Kirsher 	/* Free the transmitted descriptor */
821a88394cfSJeff Kirsher 	if ( db->cr5_data & 0x01)
822a88394cfSJeff Kirsher 		dmfe_free_tx_pkt(dev, db);
823a88394cfSJeff Kirsher 
824a88394cfSJeff Kirsher 	/* Mode Check */
825a88394cfSJeff Kirsher 	if (db->dm910x_chk_mode & 0x2) {
826a88394cfSJeff Kirsher 		db->dm910x_chk_mode = 0x4;
827a88394cfSJeff Kirsher 		db->cr6_data |= 0x100;
8285820e97aSFrancois Romieu 		update_cr6(db->cr6_data, ioaddr);
829a88394cfSJeff Kirsher 	}
830a88394cfSJeff Kirsher 
831a88394cfSJeff Kirsher 	/* Restore CR7 to enable interrupt mask */
8325820e97aSFrancois Romieu 	dw32(DCR7, db->cr7_data);
833a88394cfSJeff Kirsher 
834a88394cfSJeff Kirsher 	spin_unlock_irqrestore(&db->lock, flags);
835a88394cfSJeff Kirsher 	return IRQ_HANDLED;
836a88394cfSJeff Kirsher }
837a88394cfSJeff Kirsher 
838a88394cfSJeff Kirsher 
839a88394cfSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
840a88394cfSJeff Kirsher /*
841a88394cfSJeff Kirsher  * Polling 'interrupt' - used by things like netconsole to send skbs
842a88394cfSJeff Kirsher  * without having to re-enable interrupts. It's not called while
843a88394cfSJeff Kirsher  * the interrupt routine is executing.
844a88394cfSJeff Kirsher  */
845a88394cfSJeff Kirsher 
846a88394cfSJeff Kirsher static void poll_dmfe (struct net_device *dev)
847a88394cfSJeff Kirsher {
8485820e97aSFrancois Romieu 	struct dmfe_board_info *db = netdev_priv(dev);
8495820e97aSFrancois Romieu 	const int irq = db->pdev->irq;
8505820e97aSFrancois Romieu 
851a88394cfSJeff Kirsher 	/* disable_irq here is not very nice, but with the lockless
852a88394cfSJeff Kirsher 	   interrupt handler we have no other choice. */
8535820e97aSFrancois Romieu 	disable_irq(irq);
8545820e97aSFrancois Romieu 	dmfe_interrupt (irq, dev);
8555820e97aSFrancois Romieu 	enable_irq(irq);
856a88394cfSJeff Kirsher }
857a88394cfSJeff Kirsher #endif
858a88394cfSJeff Kirsher 
859a88394cfSJeff Kirsher /*
860a88394cfSJeff Kirsher  *	Free TX resource after TX complete
861a88394cfSJeff Kirsher  */
862a88394cfSJeff Kirsher 
863a6e5472dSFlorian Westphal static void dmfe_free_tx_pkt(struct net_device *dev, struct dmfe_board_info *db)
864a88394cfSJeff Kirsher {
865a88394cfSJeff Kirsher 	struct tx_desc *txptr;
8665820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
867a88394cfSJeff Kirsher 	u32 tdes0;
868a88394cfSJeff Kirsher 
869a88394cfSJeff Kirsher 	txptr = db->tx_remove_ptr;
870a88394cfSJeff Kirsher 	while(db->tx_packet_cnt) {
871a88394cfSJeff Kirsher 		tdes0 = le32_to_cpu(txptr->tdes0);
872a88394cfSJeff Kirsher 		if (tdes0 & 0x80000000)
873a88394cfSJeff Kirsher 			break;
874a88394cfSJeff Kirsher 
875a88394cfSJeff Kirsher 		/* A packet sent completed */
876a88394cfSJeff Kirsher 		db->tx_packet_cnt--;
877a88394cfSJeff Kirsher 		dev->stats.tx_packets++;
878a88394cfSJeff Kirsher 
879a88394cfSJeff Kirsher 		/* Transmit statistic counter */
880a88394cfSJeff Kirsher 		if ( tdes0 != 0x7fffffff ) {
881a88394cfSJeff Kirsher 			dev->stats.collisions += (tdes0 >> 3) & 0xf;
882a88394cfSJeff Kirsher 			dev->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff;
883a88394cfSJeff Kirsher 			if (tdes0 & TDES0_ERR_MASK) {
884a88394cfSJeff Kirsher 				dev->stats.tx_errors++;
885a88394cfSJeff Kirsher 
886a88394cfSJeff Kirsher 				if (tdes0 & 0x0002) {	/* UnderRun */
887a88394cfSJeff Kirsher 					db->tx_fifo_underrun++;
888a88394cfSJeff Kirsher 					if ( !(db->cr6_data & CR6_SFT) ) {
889a88394cfSJeff Kirsher 						db->cr6_data = db->cr6_data | CR6_SFT;
8905820e97aSFrancois Romieu 						update_cr6(db->cr6_data, ioaddr);
891a88394cfSJeff Kirsher 					}
892a88394cfSJeff Kirsher 				}
893a88394cfSJeff Kirsher 				if (tdes0 & 0x0100)
894a88394cfSJeff Kirsher 					db->tx_excessive_collision++;
895a88394cfSJeff Kirsher 				if (tdes0 & 0x0200)
896a88394cfSJeff Kirsher 					db->tx_late_collision++;
897a88394cfSJeff Kirsher 				if (tdes0 & 0x0400)
898a88394cfSJeff Kirsher 					db->tx_no_carrier++;
899a88394cfSJeff Kirsher 				if (tdes0 & 0x0800)
900a88394cfSJeff Kirsher 					db->tx_loss_carrier++;
901a88394cfSJeff Kirsher 				if (tdes0 & 0x4000)
902a88394cfSJeff Kirsher 					db->tx_jabber_timeout++;
903a88394cfSJeff Kirsher 			}
904a88394cfSJeff Kirsher 		}
905a88394cfSJeff Kirsher 
906a88394cfSJeff Kirsher     		txptr = txptr->next_tx_desc;
907a88394cfSJeff Kirsher 	}/* End of while */
908a88394cfSJeff Kirsher 
909a88394cfSJeff Kirsher 	/* Update TX remove pointer to next */
910a88394cfSJeff Kirsher 	db->tx_remove_ptr = txptr;
911a88394cfSJeff Kirsher 
912a88394cfSJeff Kirsher 	/* Send the Tx packet in queue */
913a88394cfSJeff Kirsher 	if ( (db->tx_packet_cnt < TX_MAX_SEND_CNT) && db->tx_queue_cnt ) {
914a88394cfSJeff Kirsher 		txptr->tdes0 = cpu_to_le32(0x80000000);	/* Set owner bit */
915a88394cfSJeff Kirsher 		db->tx_packet_cnt++;			/* Ready to send */
916a88394cfSJeff Kirsher 		db->tx_queue_cnt--;
9175820e97aSFrancois Romieu 		dw32(DCR1, 0x1);			/* Issue Tx polling */
918860e9538SFlorian Westphal 		netif_trans_update(dev);		/* saved time stamp */
919a88394cfSJeff Kirsher 	}
920a88394cfSJeff Kirsher 
921a88394cfSJeff Kirsher 	/* Resource available check */
922a88394cfSJeff Kirsher 	if ( db->tx_queue_cnt < TX_WAKE_DESC_CNT )
923a88394cfSJeff Kirsher 		netif_wake_queue(dev);	/* Active upper layer, send again */
924a88394cfSJeff Kirsher }
925a88394cfSJeff Kirsher 
926a88394cfSJeff Kirsher 
927a88394cfSJeff Kirsher /*
928a88394cfSJeff Kirsher  *	Calculate the CRC valude of the Rx packet
929a88394cfSJeff Kirsher  *	flag = 	1 : return the reverse CRC (for the received packet CRC)
930a88394cfSJeff Kirsher  *		0 : return the normal CRC (for Hash Table index)
931a88394cfSJeff Kirsher  */
932a88394cfSJeff Kirsher 
933a88394cfSJeff Kirsher static inline u32 cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
934a88394cfSJeff Kirsher {
935a88394cfSJeff Kirsher 	u32 crc = crc32(~0, Data, Len);
936a88394cfSJeff Kirsher 	if (flag) crc = ~crc;
937a88394cfSJeff Kirsher 	return crc;
938a88394cfSJeff Kirsher }
939a88394cfSJeff Kirsher 
940a88394cfSJeff Kirsher 
941a88394cfSJeff Kirsher /*
942a88394cfSJeff Kirsher  *	Receive the come packet and pass to upper layer
943a88394cfSJeff Kirsher  */
944a88394cfSJeff Kirsher 
945a6e5472dSFlorian Westphal static void dmfe_rx_packet(struct net_device *dev, struct dmfe_board_info *db)
946a88394cfSJeff Kirsher {
947a88394cfSJeff Kirsher 	struct rx_desc *rxptr;
948a88394cfSJeff Kirsher 	struct sk_buff *skb, *newskb;
949a88394cfSJeff Kirsher 	int rxlen;
950a88394cfSJeff Kirsher 	u32 rdes0;
951a88394cfSJeff Kirsher 
952a88394cfSJeff Kirsher 	rxptr = db->rx_ready_ptr;
953a88394cfSJeff Kirsher 
954a88394cfSJeff Kirsher 	while(db->rx_avail_cnt) {
955a88394cfSJeff Kirsher 		rdes0 = le32_to_cpu(rxptr->rdes0);
956a88394cfSJeff Kirsher 		if (rdes0 & 0x80000000)	/* packet owner check */
957a88394cfSJeff Kirsher 			break;
958a88394cfSJeff Kirsher 
959a88394cfSJeff Kirsher 		db->rx_avail_cnt--;
960a88394cfSJeff Kirsher 		db->interval_rx_cnt++;
961a88394cfSJeff Kirsher 
962*af114c42SChristophe JAILLET 		dma_unmap_single(&db->pdev->dev, le32_to_cpu(rxptr->rdes2),
963*af114c42SChristophe JAILLET 				 RX_ALLOC_SIZE, DMA_FROM_DEVICE);
964a88394cfSJeff Kirsher 
965a88394cfSJeff Kirsher 		if ( (rdes0 & 0x300) != 0x300) {
966a88394cfSJeff Kirsher 			/* A packet without First/Last flag */
967a88394cfSJeff Kirsher 			/* reuse this SKB */
968a88394cfSJeff Kirsher 			DMFE_DBUG(0, "Reuse SK buffer, rdes0", rdes0);
969a88394cfSJeff Kirsher 			dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
970a88394cfSJeff Kirsher 		} else {
971a88394cfSJeff Kirsher 			/* A packet with First/Last flag */
972a88394cfSJeff Kirsher 			rxlen = ( (rdes0 >> 16) & 0x3fff) - 4;
973a88394cfSJeff Kirsher 
974a88394cfSJeff Kirsher 			/* error summary bit check */
975a88394cfSJeff Kirsher 			if (rdes0 & 0x8000) {
976a88394cfSJeff Kirsher 				/* This is a error packet */
977a88394cfSJeff Kirsher 				dev->stats.rx_errors++;
978a88394cfSJeff Kirsher 				if (rdes0 & 1)
979a88394cfSJeff Kirsher 					dev->stats.rx_fifo_errors++;
980a88394cfSJeff Kirsher 				if (rdes0 & 2)
981a88394cfSJeff Kirsher 					dev->stats.rx_crc_errors++;
982a88394cfSJeff Kirsher 				if (rdes0 & 0x80)
983a88394cfSJeff Kirsher 					dev->stats.rx_length_errors++;
984a88394cfSJeff Kirsher 			}
985a88394cfSJeff Kirsher 
986a88394cfSJeff Kirsher 			if ( !(rdes0 & 0x8000) ||
987a88394cfSJeff Kirsher 				((db->cr6_data & CR6_PM) && (rxlen>6)) ) {
988a88394cfSJeff Kirsher 				skb = rxptr->rx_skb_ptr;
989a88394cfSJeff Kirsher 
990a88394cfSJeff Kirsher 				/* Received Packet CRC check need or not */
991a88394cfSJeff Kirsher 				if ( (db->dm910x_chk_mode & 1) &&
992a88394cfSJeff Kirsher 					(cal_CRC(skb->data, rxlen, 1) !=
993a88394cfSJeff Kirsher 					(*(u32 *) (skb->data+rxlen) ))) { /* FIXME (?) */
994a88394cfSJeff Kirsher 					/* Found a error received packet */
995a88394cfSJeff Kirsher 					dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
996a88394cfSJeff Kirsher 					db->dm910x_chk_mode = 3;
997a88394cfSJeff Kirsher 				} else {
998a88394cfSJeff Kirsher 					/* Good packet, send to upper layer */
999a88394cfSJeff Kirsher 					/* Shorst packet used new SKB */
1000a88394cfSJeff Kirsher 					if ((rxlen < RX_COPY_SIZE) &&
10011ab0d2ecSPradeep A. Dalvi 						((newskb = netdev_alloc_skb(dev, rxlen + 2))
1002a88394cfSJeff Kirsher 						!= NULL)) {
1003a88394cfSJeff Kirsher 
1004a88394cfSJeff Kirsher 						skb = newskb;
1005a88394cfSJeff Kirsher 						/* size less than COPY_SIZE, allocate a rxlen SKB */
1006a88394cfSJeff Kirsher 						skb_reserve(skb, 2); /* 16byte align */
1007a88394cfSJeff Kirsher 						skb_copy_from_linear_data(rxptr->rx_skb_ptr,
1008a88394cfSJeff Kirsher 							  skb_put(skb, rxlen),
1009a88394cfSJeff Kirsher 									  rxlen);
1010a88394cfSJeff Kirsher 						dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
1011a88394cfSJeff Kirsher 					} else
1012a88394cfSJeff Kirsher 						skb_put(skb, rxlen);
1013a88394cfSJeff Kirsher 
1014a88394cfSJeff Kirsher 					skb->protocol = eth_type_trans(skb, dev);
1015a88394cfSJeff Kirsher 					netif_rx(skb);
1016a88394cfSJeff Kirsher 					dev->stats.rx_packets++;
1017a88394cfSJeff Kirsher 					dev->stats.rx_bytes += rxlen;
1018a88394cfSJeff Kirsher 				}
1019a88394cfSJeff Kirsher 			} else {
1020a88394cfSJeff Kirsher 				/* Reuse SKB buffer when the packet is error */
1021a88394cfSJeff Kirsher 				DMFE_DBUG(0, "Reuse SK buffer, rdes0", rdes0);
1022a88394cfSJeff Kirsher 				dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
1023a88394cfSJeff Kirsher 			}
1024a88394cfSJeff Kirsher 		}
1025a88394cfSJeff Kirsher 
1026a88394cfSJeff Kirsher 		rxptr = rxptr->next_rx_desc;
1027a88394cfSJeff Kirsher 	}
1028a88394cfSJeff Kirsher 
1029a88394cfSJeff Kirsher 	db->rx_ready_ptr = rxptr;
1030a88394cfSJeff Kirsher }
1031a88394cfSJeff Kirsher 
1032a88394cfSJeff Kirsher /*
1033a88394cfSJeff Kirsher  * Set DM910X multicast address
1034a88394cfSJeff Kirsher  */
1035a88394cfSJeff Kirsher 
1036a6e5472dSFlorian Westphal static void dmfe_set_filter_mode(struct net_device *dev)
1037a88394cfSJeff Kirsher {
1038a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
1039a88394cfSJeff Kirsher 	unsigned long flags;
1040a88394cfSJeff Kirsher 	int mc_count = netdev_mc_count(dev);
1041a88394cfSJeff Kirsher 
1042a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_set_filter_mode()", 0);
1043a88394cfSJeff Kirsher 	spin_lock_irqsave(&db->lock, flags);
1044a88394cfSJeff Kirsher 
1045a88394cfSJeff Kirsher 	if (dev->flags & IFF_PROMISC) {
1046a88394cfSJeff Kirsher 		DMFE_DBUG(0, "Enable PROM Mode", 0);
1047a88394cfSJeff Kirsher 		db->cr6_data |= CR6_PM | CR6_PBF;
1048a88394cfSJeff Kirsher 		update_cr6(db->cr6_data, db->ioaddr);
1049a88394cfSJeff Kirsher 		spin_unlock_irqrestore(&db->lock, flags);
1050a88394cfSJeff Kirsher 		return;
1051a88394cfSJeff Kirsher 	}
1052a88394cfSJeff Kirsher 
1053a88394cfSJeff Kirsher 	if (dev->flags & IFF_ALLMULTI || mc_count > DMFE_MAX_MULTICAST) {
1054a88394cfSJeff Kirsher 		DMFE_DBUG(0, "Pass all multicast address", mc_count);
1055a88394cfSJeff Kirsher 		db->cr6_data &= ~(CR6_PM | CR6_PBF);
1056a88394cfSJeff Kirsher 		db->cr6_data |= CR6_PAM;
1057a88394cfSJeff Kirsher 		spin_unlock_irqrestore(&db->lock, flags);
1058a88394cfSJeff Kirsher 		return;
1059a88394cfSJeff Kirsher 	}
1060a88394cfSJeff Kirsher 
1061a88394cfSJeff Kirsher 	DMFE_DBUG(0, "Set multicast address", mc_count);
1062a88394cfSJeff Kirsher 	if (db->chip_id == PCI_DM9132_ID)
1063a88394cfSJeff Kirsher 		dm9132_id_table(dev);	/* DM9132 */
1064a88394cfSJeff Kirsher 	else
1065a88394cfSJeff Kirsher 		send_filter_frame(dev);	/* DM9102/DM9102A */
1066a88394cfSJeff Kirsher 	spin_unlock_irqrestore(&db->lock, flags);
1067a88394cfSJeff Kirsher }
1068a88394cfSJeff Kirsher 
1069a88394cfSJeff Kirsher /*
1070a88394cfSJeff Kirsher  * 	Ethtool interace
1071a88394cfSJeff Kirsher  */
1072a88394cfSJeff Kirsher 
1073a88394cfSJeff Kirsher static void dmfe_ethtool_get_drvinfo(struct net_device *dev,
1074a88394cfSJeff Kirsher 			       struct ethtool_drvinfo *info)
1075a88394cfSJeff Kirsher {
1076a88394cfSJeff Kirsher 	struct dmfe_board_info *np = netdev_priv(dev);
1077a88394cfSJeff Kirsher 
107868aad78cSRick Jones 	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
10795820e97aSFrancois Romieu 	strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info));
1080a88394cfSJeff Kirsher }
1081a88394cfSJeff Kirsher 
1082a88394cfSJeff Kirsher static int dmfe_ethtool_set_wol(struct net_device *dev,
1083a88394cfSJeff Kirsher 				struct ethtool_wolinfo *wolinfo)
1084a88394cfSJeff Kirsher {
1085a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
1086a88394cfSJeff Kirsher 
1087a88394cfSJeff Kirsher 	if (wolinfo->wolopts & (WAKE_UCAST | WAKE_MCAST | WAKE_BCAST |
1088a88394cfSJeff Kirsher 		   		WAKE_ARP | WAKE_MAGICSECURE))
1089a88394cfSJeff Kirsher 		   return -EOPNOTSUPP;
1090a88394cfSJeff Kirsher 
1091a88394cfSJeff Kirsher 	db->wol_mode = wolinfo->wolopts;
1092a88394cfSJeff Kirsher 	return 0;
1093a88394cfSJeff Kirsher }
1094a88394cfSJeff Kirsher 
1095a88394cfSJeff Kirsher static void dmfe_ethtool_get_wol(struct net_device *dev,
1096a88394cfSJeff Kirsher 				 struct ethtool_wolinfo *wolinfo)
1097a88394cfSJeff Kirsher {
1098a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
1099a88394cfSJeff Kirsher 
1100a88394cfSJeff Kirsher 	wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
1101a88394cfSJeff Kirsher 	wolinfo->wolopts = db->wol_mode;
1102a88394cfSJeff Kirsher }
1103a88394cfSJeff Kirsher 
1104a88394cfSJeff Kirsher 
1105a88394cfSJeff Kirsher static const struct ethtool_ops netdev_ethtool_ops = {
1106a88394cfSJeff Kirsher 	.get_drvinfo		= dmfe_ethtool_get_drvinfo,
1107a88394cfSJeff Kirsher 	.get_link               = ethtool_op_get_link,
1108a88394cfSJeff Kirsher 	.set_wol		= dmfe_ethtool_set_wol,
1109a88394cfSJeff Kirsher 	.get_wol		= dmfe_ethtool_get_wol,
1110a88394cfSJeff Kirsher };
1111a88394cfSJeff Kirsher 
1112a88394cfSJeff Kirsher /*
1113a88394cfSJeff Kirsher  *	A periodic timer routine
1114a88394cfSJeff Kirsher  *	Dynamic media sense, allocate Rx buffer...
1115a88394cfSJeff Kirsher  */
1116a88394cfSJeff Kirsher 
1117a8c22a2bSKees Cook static void dmfe_timer(struct timer_list *t)
1118a88394cfSJeff Kirsher {
1119a8c22a2bSKees Cook 	struct dmfe_board_info *db = from_timer(db, t, timer);
1120a8c22a2bSKees Cook 	struct net_device *dev = pci_get_drvdata(db->pdev);
11215820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
1122a88394cfSJeff Kirsher 	u32 tmp_cr8;
1123a88394cfSJeff Kirsher 	unsigned char tmp_cr12;
1124a88394cfSJeff Kirsher  	unsigned long flags;
1125a88394cfSJeff Kirsher 
1126a88394cfSJeff Kirsher 	int link_ok, link_ok_phy;
1127a88394cfSJeff Kirsher 
1128a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_timer()", 0);
1129a88394cfSJeff Kirsher 	spin_lock_irqsave(&db->lock, flags);
1130a88394cfSJeff Kirsher 
1131a88394cfSJeff Kirsher 	/* Media mode process when Link OK before enter this route */
1132a88394cfSJeff Kirsher 	if (db->first_in_callback == 0) {
1133a88394cfSJeff Kirsher 		db->first_in_callback = 1;
1134a88394cfSJeff Kirsher 		if (db->chip_type && (db->chip_id==PCI_DM9102_ID)) {
1135a88394cfSJeff Kirsher 			db->cr6_data &= ~0x40000;
11365820e97aSFrancois Romieu 			update_cr6(db->cr6_data, ioaddr);
113773852b2bSDavid S. Miller 			dmfe_phy_write(ioaddr, db->phy_addr, 0, 0x1000, db->chip_id);
1138a88394cfSJeff Kirsher 			db->cr6_data |= 0x40000;
11395820e97aSFrancois Romieu 			update_cr6(db->cr6_data, ioaddr);
1140a88394cfSJeff Kirsher 			db->timer.expires = DMFE_TIMER_WUT + HZ * 2;
1141a88394cfSJeff Kirsher 			add_timer(&db->timer);
1142a88394cfSJeff Kirsher 			spin_unlock_irqrestore(&db->lock, flags);
1143a88394cfSJeff Kirsher 			return;
1144a88394cfSJeff Kirsher 		}
1145a88394cfSJeff Kirsher 	}
1146a88394cfSJeff Kirsher 
1147a88394cfSJeff Kirsher 
1148a88394cfSJeff Kirsher 	/* Operating Mode Check */
1149a88394cfSJeff Kirsher 	if ( (db->dm910x_chk_mode & 0x1) &&
1150a88394cfSJeff Kirsher 		(dev->stats.rx_packets > MAX_CHECK_PACKET) )
1151a88394cfSJeff Kirsher 		db->dm910x_chk_mode = 0x4;
1152a88394cfSJeff Kirsher 
1153a88394cfSJeff Kirsher 	/* Dynamic reset DM910X : system error or transmit time-out */
11545820e97aSFrancois Romieu 	tmp_cr8 = dr32(DCR8);
1155a88394cfSJeff Kirsher 	if ( (db->interval_rx_cnt==0) && (tmp_cr8) ) {
1156a88394cfSJeff Kirsher 		db->reset_cr8++;
1157a88394cfSJeff Kirsher 		db->wait_reset = 1;
1158a88394cfSJeff Kirsher 	}
1159a88394cfSJeff Kirsher 	db->interval_rx_cnt = 0;
1160a88394cfSJeff Kirsher 
1161a88394cfSJeff Kirsher 	/* TX polling kick monitor */
1162a88394cfSJeff Kirsher 	if ( db->tx_packet_cnt &&
1163a88394cfSJeff Kirsher 	     time_after(jiffies, dev_trans_start(dev) + DMFE_TX_KICK) ) {
11645820e97aSFrancois Romieu 		dw32(DCR1, 0x1);   /* Tx polling again */
1165a88394cfSJeff Kirsher 
1166a88394cfSJeff Kirsher 		/* TX Timeout */
1167a88394cfSJeff Kirsher 		if (time_after(jiffies, dev_trans_start(dev) + DMFE_TX_TIMEOUT) ) {
1168a88394cfSJeff Kirsher 			db->reset_TXtimeout++;
1169a88394cfSJeff Kirsher 			db->wait_reset = 1;
1170a88394cfSJeff Kirsher 			dev_warn(&dev->dev, "Tx timeout - resetting\n");
1171a88394cfSJeff Kirsher 		}
1172a88394cfSJeff Kirsher 	}
1173a88394cfSJeff Kirsher 
1174a88394cfSJeff Kirsher 	if (db->wait_reset) {
1175a88394cfSJeff Kirsher 		DMFE_DBUG(0, "Dynamic Reset device", db->tx_packet_cnt);
1176a88394cfSJeff Kirsher 		db->reset_count++;
1177a88394cfSJeff Kirsher 		dmfe_dynamic_reset(dev);
1178a88394cfSJeff Kirsher 		db->first_in_callback = 0;
1179a88394cfSJeff Kirsher 		db->timer.expires = DMFE_TIMER_WUT;
1180a88394cfSJeff Kirsher 		add_timer(&db->timer);
1181a88394cfSJeff Kirsher 		spin_unlock_irqrestore(&db->lock, flags);
1182a88394cfSJeff Kirsher 		return;
1183a88394cfSJeff Kirsher 	}
1184a88394cfSJeff Kirsher 
1185a88394cfSJeff Kirsher 	/* Link status check, Dynamic media type change */
1186a88394cfSJeff Kirsher 	if (db->chip_id == PCI_DM9132_ID)
11875820e97aSFrancois Romieu 		tmp_cr12 = dr8(DCR9 + 3);	/* DM9132 */
1188a88394cfSJeff Kirsher 	else
11895820e97aSFrancois Romieu 		tmp_cr12 = dr8(DCR12);		/* DM9102/DM9102A */
1190a88394cfSJeff Kirsher 
1191a88394cfSJeff Kirsher 	if ( ((db->chip_id == PCI_DM9102_ID) &&
1192a88394cfSJeff Kirsher 		(db->chip_revision == 0x30)) ||
1193a88394cfSJeff Kirsher 		((db->chip_id == PCI_DM9132_ID) &&
1194a88394cfSJeff Kirsher 		(db->chip_revision == 0x10)) ) {
1195a88394cfSJeff Kirsher 		/* DM9102A Chip */
1196a88394cfSJeff Kirsher 		if (tmp_cr12 & 2)
1197a88394cfSJeff Kirsher 			link_ok = 0;
1198a88394cfSJeff Kirsher 		else
1199a88394cfSJeff Kirsher 			link_ok = 1;
1200a88394cfSJeff Kirsher 	}
1201a88394cfSJeff Kirsher 	else
1202a88394cfSJeff Kirsher 		/*0x43 is used instead of 0x3 because bit 6 should represent
1203a88394cfSJeff Kirsher 			link status of external PHY */
1204a88394cfSJeff Kirsher 		link_ok = (tmp_cr12 & 0x43) ? 1 : 0;
1205a88394cfSJeff Kirsher 
1206a88394cfSJeff Kirsher 
1207a88394cfSJeff Kirsher 	/* If chip reports that link is failed it could be because external
1208a88394cfSJeff Kirsher 		PHY link status pin is not connected correctly to chip
1209a88394cfSJeff Kirsher 		To be sure ask PHY too.
1210a88394cfSJeff Kirsher 	*/
1211a88394cfSJeff Kirsher 
1212a88394cfSJeff Kirsher 	/* need a dummy read because of PHY's register latch*/
121373852b2bSDavid S. Miller 	dmfe_phy_read (db->ioaddr, db->phy_addr, 1, db->chip_id);
121473852b2bSDavid S. Miller 	link_ok_phy = (dmfe_phy_read (db->ioaddr,
1215a88394cfSJeff Kirsher 				      db->phy_addr, 1, db->chip_id) & 0x4) ? 1 : 0;
1216a88394cfSJeff Kirsher 
1217a88394cfSJeff Kirsher 	if (link_ok_phy != link_ok) {
1218a88394cfSJeff Kirsher 		DMFE_DBUG (0, "PHY and chip report different link status", 0);
1219a88394cfSJeff Kirsher 		link_ok = link_ok | link_ok_phy;
1220a88394cfSJeff Kirsher  	}
1221a88394cfSJeff Kirsher 
1222a88394cfSJeff Kirsher 	if ( !link_ok && netif_carrier_ok(dev)) {
1223a88394cfSJeff Kirsher 		/* Link Failed */
1224a88394cfSJeff Kirsher 		DMFE_DBUG(0, "Link Failed", tmp_cr12);
1225a88394cfSJeff Kirsher 		netif_carrier_off(dev);
1226a88394cfSJeff Kirsher 
1227a88394cfSJeff Kirsher 		/* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */
1228a88394cfSJeff Kirsher 		/* AUTO or force 1M Homerun/Longrun don't need */
1229a88394cfSJeff Kirsher 		if ( !(db->media_mode & 0x38) )
123073852b2bSDavid S. Miller 			dmfe_phy_write(db->ioaddr, db->phy_addr,
1231a88394cfSJeff Kirsher 				       0, 0x1000, db->chip_id);
1232a88394cfSJeff Kirsher 
1233a88394cfSJeff Kirsher 		/* AUTO mode, if INT phyxcer link failed, select EXT device */
1234a88394cfSJeff Kirsher 		if (db->media_mode & DMFE_AUTO) {
1235a88394cfSJeff Kirsher 			/* 10/100M link failed, used 1M Home-Net */
1236a88394cfSJeff Kirsher 			db->cr6_data|=0x00040000;	/* bit18=1, MII */
1237a88394cfSJeff Kirsher 			db->cr6_data&=~0x00000200;	/* bit9=0, HD mode */
12385820e97aSFrancois Romieu 			update_cr6(db->cr6_data, ioaddr);
1239a88394cfSJeff Kirsher 		}
1240a88394cfSJeff Kirsher 	} else if (!netif_carrier_ok(dev)) {
1241a88394cfSJeff Kirsher 
1242a88394cfSJeff Kirsher 		DMFE_DBUG(0, "Link link OK", tmp_cr12);
1243a88394cfSJeff Kirsher 
1244a88394cfSJeff Kirsher 		/* Auto Sense Speed */
1245a88394cfSJeff Kirsher 		if ( !(db->media_mode & DMFE_AUTO) || !dmfe_sense_speed(db)) {
1246a88394cfSJeff Kirsher 			netif_carrier_on(dev);
1247a88394cfSJeff Kirsher 			SHOW_MEDIA_TYPE(db->op_mode);
1248a88394cfSJeff Kirsher 		}
1249a88394cfSJeff Kirsher 
1250a88394cfSJeff Kirsher 		dmfe_process_mode(db);
1251a88394cfSJeff Kirsher 	}
1252a88394cfSJeff Kirsher 
1253a88394cfSJeff Kirsher 	/* HPNA remote command check */
1254a88394cfSJeff Kirsher 	if (db->HPNA_command & 0xf00) {
1255a88394cfSJeff Kirsher 		db->HPNA_timer--;
1256a88394cfSJeff Kirsher 		if (!db->HPNA_timer)
1257a88394cfSJeff Kirsher 			dmfe_HPNA_remote_cmd_chk(db);
1258a88394cfSJeff Kirsher 	}
1259a88394cfSJeff Kirsher 
1260a88394cfSJeff Kirsher 	/* Timer active again */
1261a88394cfSJeff Kirsher 	db->timer.expires = DMFE_TIMER_WUT;
1262a88394cfSJeff Kirsher 	add_timer(&db->timer);
1263a88394cfSJeff Kirsher 	spin_unlock_irqrestore(&db->lock, flags);
1264a88394cfSJeff Kirsher }
1265a88394cfSJeff Kirsher 
1266a88394cfSJeff Kirsher 
1267a88394cfSJeff Kirsher /*
1268a88394cfSJeff Kirsher  *	Dynamic reset the DM910X board
1269a88394cfSJeff Kirsher  *	Stop DM910X board
1270a88394cfSJeff Kirsher  *	Free Tx/Rx allocated memory
1271a88394cfSJeff Kirsher  *	Reset DM910X board
1272a88394cfSJeff Kirsher  *	Re-initialize DM910X board
1273a88394cfSJeff Kirsher  */
1274a88394cfSJeff Kirsher 
12755820e97aSFrancois Romieu static void dmfe_dynamic_reset(struct net_device *dev)
1276a88394cfSJeff Kirsher {
1277a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
12785820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
1279a88394cfSJeff Kirsher 
1280a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_dynamic_reset()", 0);
1281a88394cfSJeff Kirsher 
1282a88394cfSJeff Kirsher 	/* Sopt MAC controller */
1283a88394cfSJeff Kirsher 	db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);	/* Disable Tx/Rx */
12845820e97aSFrancois Romieu 	update_cr6(db->cr6_data, ioaddr);
12855820e97aSFrancois Romieu 	dw32(DCR7, 0);				/* Disable Interrupt */
12865820e97aSFrancois Romieu 	dw32(DCR5, dr32(DCR5));
1287a88394cfSJeff Kirsher 
1288a88394cfSJeff Kirsher 	/* Disable upper layer interface */
1289a88394cfSJeff Kirsher 	netif_stop_queue(dev);
1290a88394cfSJeff Kirsher 
1291a88394cfSJeff Kirsher 	/* Free Rx Allocate buffer */
1292a88394cfSJeff Kirsher 	dmfe_free_rxbuffer(db);
1293a88394cfSJeff Kirsher 
1294a88394cfSJeff Kirsher 	/* system variable init */
1295a88394cfSJeff Kirsher 	db->tx_packet_cnt = 0;
1296a88394cfSJeff Kirsher 	db->tx_queue_cnt = 0;
1297a88394cfSJeff Kirsher 	db->rx_avail_cnt = 0;
1298a88394cfSJeff Kirsher 	netif_carrier_off(dev);
1299a88394cfSJeff Kirsher 	db->wait_reset = 0;
1300a88394cfSJeff Kirsher 
1301a88394cfSJeff Kirsher 	/* Re-initialize DM910X board */
1302a88394cfSJeff Kirsher 	dmfe_init_dm910x(dev);
1303a88394cfSJeff Kirsher 
1304a88394cfSJeff Kirsher 	/* Restart upper layer interface */
1305a88394cfSJeff Kirsher 	netif_wake_queue(dev);
1306a88394cfSJeff Kirsher }
1307a88394cfSJeff Kirsher 
1308a88394cfSJeff Kirsher 
1309a88394cfSJeff Kirsher /*
1310a88394cfSJeff Kirsher  *	free all allocated rx buffer
1311a88394cfSJeff Kirsher  */
1312a88394cfSJeff Kirsher 
1313a88394cfSJeff Kirsher static void dmfe_free_rxbuffer(struct dmfe_board_info * db)
1314a88394cfSJeff Kirsher {
1315a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_free_rxbuffer()", 0);
1316a88394cfSJeff Kirsher 
1317a88394cfSJeff Kirsher 	/* free allocated rx buffer */
1318a88394cfSJeff Kirsher 	while (db->rx_avail_cnt) {
1319a88394cfSJeff Kirsher 		dev_kfree_skb(db->rx_ready_ptr->rx_skb_ptr);
1320a88394cfSJeff Kirsher 		db->rx_ready_ptr = db->rx_ready_ptr->next_rx_desc;
1321a88394cfSJeff Kirsher 		db->rx_avail_cnt--;
1322a88394cfSJeff Kirsher 	}
1323a88394cfSJeff Kirsher }
1324a88394cfSJeff Kirsher 
1325a88394cfSJeff Kirsher 
1326a88394cfSJeff Kirsher /*
1327a88394cfSJeff Kirsher  *	Reuse the SK buffer
1328a88394cfSJeff Kirsher  */
1329a88394cfSJeff Kirsher 
1330a88394cfSJeff Kirsher static void dmfe_reuse_skb(struct dmfe_board_info *db, struct sk_buff * skb)
1331a88394cfSJeff Kirsher {
1332a88394cfSJeff Kirsher 	struct rx_desc *rxptr = db->rx_insert_ptr;
1333a88394cfSJeff Kirsher 
1334a88394cfSJeff Kirsher 	if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) {
1335a88394cfSJeff Kirsher 		rxptr->rx_skb_ptr = skb;
1336*af114c42SChristophe JAILLET 		rxptr->rdes2 = cpu_to_le32(dma_map_single(&db->pdev->dev, skb->data,
1337*af114c42SChristophe JAILLET 							  RX_ALLOC_SIZE, DMA_FROM_DEVICE));
1338a88394cfSJeff Kirsher 		wmb();
1339a88394cfSJeff Kirsher 		rxptr->rdes0 = cpu_to_le32(0x80000000);
1340a88394cfSJeff Kirsher 		db->rx_avail_cnt++;
1341a88394cfSJeff Kirsher 		db->rx_insert_ptr = rxptr->next_rx_desc;
1342a88394cfSJeff Kirsher 	} else
1343a88394cfSJeff Kirsher 		DMFE_DBUG(0, "SK Buffer reuse method error", db->rx_avail_cnt);
1344a88394cfSJeff Kirsher }
1345a88394cfSJeff Kirsher 
1346a88394cfSJeff Kirsher 
1347a88394cfSJeff Kirsher /*
1348a88394cfSJeff Kirsher  *	Initialize transmit/Receive descriptor
1349a88394cfSJeff Kirsher  *	Using Chain structure, and allocate Tx/Rx buffer
1350a88394cfSJeff Kirsher  */
1351a88394cfSJeff Kirsher 
13525820e97aSFrancois Romieu static void dmfe_descriptor_init(struct net_device *dev)
1353a88394cfSJeff Kirsher {
13541ab0d2ecSPradeep A. Dalvi 	struct dmfe_board_info *db = netdev_priv(dev);
13555820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
1356a88394cfSJeff Kirsher 	struct tx_desc *tmp_tx;
1357a88394cfSJeff Kirsher 	struct rx_desc *tmp_rx;
1358a88394cfSJeff Kirsher 	unsigned char *tmp_buf;
1359a88394cfSJeff Kirsher 	dma_addr_t tmp_tx_dma, tmp_rx_dma;
1360a88394cfSJeff Kirsher 	dma_addr_t tmp_buf_dma;
1361a88394cfSJeff Kirsher 	int i;
1362a88394cfSJeff Kirsher 
1363a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_descriptor_init()", 0);
1364a88394cfSJeff Kirsher 
1365a88394cfSJeff Kirsher 	/* tx descriptor start pointer */
1366a88394cfSJeff Kirsher 	db->tx_insert_ptr = db->first_tx_desc;
1367a88394cfSJeff Kirsher 	db->tx_remove_ptr = db->first_tx_desc;
13685820e97aSFrancois Romieu 	dw32(DCR4, db->first_tx_desc_dma);     /* TX DESC address */
1369a88394cfSJeff Kirsher 
1370a88394cfSJeff Kirsher 	/* rx descriptor start pointer */
1371a88394cfSJeff Kirsher 	db->first_rx_desc = (void *)db->first_tx_desc +
1372a88394cfSJeff Kirsher 			sizeof(struct tx_desc) * TX_DESC_CNT;
1373a88394cfSJeff Kirsher 
1374a88394cfSJeff Kirsher 	db->first_rx_desc_dma =  db->first_tx_desc_dma +
1375a88394cfSJeff Kirsher 			sizeof(struct tx_desc) * TX_DESC_CNT;
1376a88394cfSJeff Kirsher 	db->rx_insert_ptr = db->first_rx_desc;
1377a88394cfSJeff Kirsher 	db->rx_ready_ptr = db->first_rx_desc;
13785820e97aSFrancois Romieu 	dw32(DCR3, db->first_rx_desc_dma);		/* RX DESC address */
1379a88394cfSJeff Kirsher 
1380a88394cfSJeff Kirsher 	/* Init Transmit chain */
1381a88394cfSJeff Kirsher 	tmp_buf = db->buf_pool_start;
1382a88394cfSJeff Kirsher 	tmp_buf_dma = db->buf_pool_dma_start;
1383a88394cfSJeff Kirsher 	tmp_tx_dma = db->first_tx_desc_dma;
1384a88394cfSJeff Kirsher 	for (tmp_tx = db->first_tx_desc, i = 0; i < TX_DESC_CNT; i++, tmp_tx++) {
1385a88394cfSJeff Kirsher 		tmp_tx->tx_buf_ptr = tmp_buf;
1386a88394cfSJeff Kirsher 		tmp_tx->tdes0 = cpu_to_le32(0);
1387a88394cfSJeff Kirsher 		tmp_tx->tdes1 = cpu_to_le32(0x81000000);	/* IC, chain */
1388a88394cfSJeff Kirsher 		tmp_tx->tdes2 = cpu_to_le32(tmp_buf_dma);
1389a88394cfSJeff Kirsher 		tmp_tx_dma += sizeof(struct tx_desc);
1390a88394cfSJeff Kirsher 		tmp_tx->tdes3 = cpu_to_le32(tmp_tx_dma);
1391a88394cfSJeff Kirsher 		tmp_tx->next_tx_desc = tmp_tx + 1;
1392a88394cfSJeff Kirsher 		tmp_buf = tmp_buf + TX_BUF_ALLOC;
1393a88394cfSJeff Kirsher 		tmp_buf_dma = tmp_buf_dma + TX_BUF_ALLOC;
1394a88394cfSJeff Kirsher 	}
1395a88394cfSJeff Kirsher 	(--tmp_tx)->tdes3 = cpu_to_le32(db->first_tx_desc_dma);
1396a88394cfSJeff Kirsher 	tmp_tx->next_tx_desc = db->first_tx_desc;
1397a88394cfSJeff Kirsher 
1398a88394cfSJeff Kirsher 	 /* Init Receive descriptor chain */
1399a88394cfSJeff Kirsher 	tmp_rx_dma=db->first_rx_desc_dma;
1400a88394cfSJeff Kirsher 	for (tmp_rx = db->first_rx_desc, i = 0; i < RX_DESC_CNT; i++, tmp_rx++) {
1401a88394cfSJeff Kirsher 		tmp_rx->rdes0 = cpu_to_le32(0);
1402a88394cfSJeff Kirsher 		tmp_rx->rdes1 = cpu_to_le32(0x01000600);
1403a88394cfSJeff Kirsher 		tmp_rx_dma += sizeof(struct rx_desc);
1404a88394cfSJeff Kirsher 		tmp_rx->rdes3 = cpu_to_le32(tmp_rx_dma);
1405a88394cfSJeff Kirsher 		tmp_rx->next_rx_desc = tmp_rx + 1;
1406a88394cfSJeff Kirsher 	}
1407a88394cfSJeff Kirsher 	(--tmp_rx)->rdes3 = cpu_to_le32(db->first_rx_desc_dma);
1408a88394cfSJeff Kirsher 	tmp_rx->next_rx_desc = db->first_rx_desc;
1409a88394cfSJeff Kirsher 
1410a88394cfSJeff Kirsher 	/* pre-allocate Rx buffer */
14111ab0d2ecSPradeep A. Dalvi 	allocate_rx_buffer(dev);
1412a88394cfSJeff Kirsher }
1413a88394cfSJeff Kirsher 
1414a88394cfSJeff Kirsher 
1415a88394cfSJeff Kirsher /*
1416a88394cfSJeff Kirsher  *	Update CR6 value
1417a88394cfSJeff Kirsher  *	Firstly stop DM910X , then written value and start
1418a88394cfSJeff Kirsher  */
1419a88394cfSJeff Kirsher 
14205820e97aSFrancois Romieu static void update_cr6(u32 cr6_data, void __iomem *ioaddr)
1421a88394cfSJeff Kirsher {
1422a88394cfSJeff Kirsher 	u32 cr6_tmp;
1423a88394cfSJeff Kirsher 
1424a88394cfSJeff Kirsher 	cr6_tmp = cr6_data & ~0x2002;           /* stop Tx/Rx */
14255820e97aSFrancois Romieu 	dw32(DCR6, cr6_tmp);
1426a88394cfSJeff Kirsher 	udelay(5);
14275820e97aSFrancois Romieu 	dw32(DCR6, cr6_data);
1428a88394cfSJeff Kirsher 	udelay(5);
1429a88394cfSJeff Kirsher }
1430a88394cfSJeff Kirsher 
1431a88394cfSJeff Kirsher 
1432a88394cfSJeff Kirsher /*
1433a88394cfSJeff Kirsher  *	Send a setup frame for DM9132
1434a88394cfSJeff Kirsher  *	This setup frame initialize DM910X address filter mode
1435a88394cfSJeff Kirsher */
1436a88394cfSJeff Kirsher 
14375820e97aSFrancois Romieu static void dm9132_id_table(struct net_device *dev)
1438a88394cfSJeff Kirsher {
14395820e97aSFrancois Romieu 	struct dmfe_board_info *db = netdev_priv(dev);
14405820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr + 0xc0;
14415820e97aSFrancois Romieu 	u16 *addrptr = (u16 *)dev->dev_addr;
1442a88394cfSJeff Kirsher 	struct netdev_hw_addr *ha;
1443a88394cfSJeff Kirsher 	u16 i, hash_table[4];
1444a88394cfSJeff Kirsher 
1445a88394cfSJeff Kirsher 	/* Node address */
14465820e97aSFrancois Romieu 	for (i = 0; i < 3; i++) {
14475820e97aSFrancois Romieu 		dw16(0, addrptr[i]);
1448a88394cfSJeff Kirsher 		ioaddr += 4;
14495820e97aSFrancois Romieu 	}
1450a88394cfSJeff Kirsher 
1451a88394cfSJeff Kirsher 	/* Clear Hash Table */
1452a88394cfSJeff Kirsher 	memset(hash_table, 0, sizeof(hash_table));
1453a88394cfSJeff Kirsher 
1454a88394cfSJeff Kirsher 	/* broadcast address */
1455a88394cfSJeff Kirsher 	hash_table[3] = 0x8000;
1456a88394cfSJeff Kirsher 
1457a88394cfSJeff Kirsher 	/* the multicast address in Hash Table : 64 bits */
1458a88394cfSJeff Kirsher 	netdev_for_each_mc_addr(ha, dev) {
14595820e97aSFrancois Romieu 		u32 hash_val = cal_CRC((char *)ha->addr, 6, 0) & 0x3f;
14605820e97aSFrancois Romieu 
1461a88394cfSJeff Kirsher 		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
1462a88394cfSJeff Kirsher 	}
1463a88394cfSJeff Kirsher 
1464a88394cfSJeff Kirsher 	/* Write the hash table to MAC MD table */
1465a88394cfSJeff Kirsher 	for (i = 0; i < 4; i++, ioaddr += 4)
14665820e97aSFrancois Romieu 		dw16(0, hash_table[i]);
1467a88394cfSJeff Kirsher }
1468a88394cfSJeff Kirsher 
1469a88394cfSJeff Kirsher 
1470a88394cfSJeff Kirsher /*
1471a88394cfSJeff Kirsher  *	Send a setup frame for DM9102/DM9102A
1472a88394cfSJeff Kirsher  *	This setup frame initialize DM910X address filter mode
1473a88394cfSJeff Kirsher  */
1474a88394cfSJeff Kirsher 
14755820e97aSFrancois Romieu static void send_filter_frame(struct net_device *dev)
1476a88394cfSJeff Kirsher {
1477a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
1478a88394cfSJeff Kirsher 	struct netdev_hw_addr *ha;
1479a88394cfSJeff Kirsher 	struct tx_desc *txptr;
1480a88394cfSJeff Kirsher 	u16 * addrptr;
1481a88394cfSJeff Kirsher 	u32 * suptr;
1482a88394cfSJeff Kirsher 	int i;
1483a88394cfSJeff Kirsher 
1484a88394cfSJeff Kirsher 	DMFE_DBUG(0, "send_filter_frame()", 0);
1485a88394cfSJeff Kirsher 
1486a88394cfSJeff Kirsher 	txptr = db->tx_insert_ptr;
1487a88394cfSJeff Kirsher 	suptr = (u32 *) txptr->tx_buf_ptr;
1488a88394cfSJeff Kirsher 
1489a88394cfSJeff Kirsher 	/* Node address */
1490a88394cfSJeff Kirsher 	addrptr = (u16 *) dev->dev_addr;
1491a88394cfSJeff Kirsher 	*suptr++ = addrptr[0];
1492a88394cfSJeff Kirsher 	*suptr++ = addrptr[1];
1493a88394cfSJeff Kirsher 	*suptr++ = addrptr[2];
1494a88394cfSJeff Kirsher 
1495a88394cfSJeff Kirsher 	/* broadcast address */
1496a88394cfSJeff Kirsher 	*suptr++ = 0xffff;
1497a88394cfSJeff Kirsher 	*suptr++ = 0xffff;
1498a88394cfSJeff Kirsher 	*suptr++ = 0xffff;
1499a88394cfSJeff Kirsher 
1500a88394cfSJeff Kirsher 	/* fit the multicast address */
1501a88394cfSJeff Kirsher 	netdev_for_each_mc_addr(ha, dev) {
1502a88394cfSJeff Kirsher 		addrptr = (u16 *) ha->addr;
1503a88394cfSJeff Kirsher 		*suptr++ = addrptr[0];
1504a88394cfSJeff Kirsher 		*suptr++ = addrptr[1];
1505a88394cfSJeff Kirsher 		*suptr++ = addrptr[2];
1506a88394cfSJeff Kirsher 	}
1507a88394cfSJeff Kirsher 
1508a88394cfSJeff Kirsher 	for (i = netdev_mc_count(dev); i < 14; i++) {
1509a88394cfSJeff Kirsher 		*suptr++ = 0xffff;
1510a88394cfSJeff Kirsher 		*suptr++ = 0xffff;
1511a88394cfSJeff Kirsher 		*suptr++ = 0xffff;
1512a88394cfSJeff Kirsher 	}
1513a88394cfSJeff Kirsher 
1514a88394cfSJeff Kirsher 	/* prepare the setup frame */
1515a88394cfSJeff Kirsher 	db->tx_insert_ptr = txptr->next_tx_desc;
1516a88394cfSJeff Kirsher 	txptr->tdes1 = cpu_to_le32(0x890000c0);
1517a88394cfSJeff Kirsher 
1518a88394cfSJeff Kirsher 	/* Resource Check and Send the setup packet */
1519a88394cfSJeff Kirsher 	if (!db->tx_packet_cnt) {
15205820e97aSFrancois Romieu 		void __iomem *ioaddr = db->ioaddr;
15215820e97aSFrancois Romieu 
1522a88394cfSJeff Kirsher 		/* Resource Empty */
1523a88394cfSJeff Kirsher 		db->tx_packet_cnt++;
1524a88394cfSJeff Kirsher 		txptr->tdes0 = cpu_to_le32(0x80000000);
15255820e97aSFrancois Romieu 		update_cr6(db->cr6_data | 0x2000, ioaddr);
15265820e97aSFrancois Romieu 		dw32(DCR1, 0x1);	/* Issue Tx polling */
15275820e97aSFrancois Romieu 		update_cr6(db->cr6_data, ioaddr);
1528860e9538SFlorian Westphal 		netif_trans_update(dev);
1529a88394cfSJeff Kirsher 	} else
1530a88394cfSJeff Kirsher 		db->tx_queue_cnt++;	/* Put in TX queue */
1531a88394cfSJeff Kirsher }
1532a88394cfSJeff Kirsher 
1533a88394cfSJeff Kirsher 
1534a88394cfSJeff Kirsher /*
1535a88394cfSJeff Kirsher  *	Allocate rx buffer,
1536a88394cfSJeff Kirsher  *	As possible as allocate maxiumn Rx buffer
1537a88394cfSJeff Kirsher  */
1538a88394cfSJeff Kirsher 
15391ab0d2ecSPradeep A. Dalvi static void allocate_rx_buffer(struct net_device *dev)
1540a88394cfSJeff Kirsher {
15411ab0d2ecSPradeep A. Dalvi 	struct dmfe_board_info *db = netdev_priv(dev);
1542a88394cfSJeff Kirsher 	struct rx_desc *rxptr;
1543a88394cfSJeff Kirsher 	struct sk_buff *skb;
1544a88394cfSJeff Kirsher 
1545a88394cfSJeff Kirsher 	rxptr = db->rx_insert_ptr;
1546a88394cfSJeff Kirsher 
1547a88394cfSJeff Kirsher 	while(db->rx_avail_cnt < RX_DESC_CNT) {
15481ab0d2ecSPradeep A. Dalvi 		if ( ( skb = netdev_alloc_skb(dev, RX_ALLOC_SIZE) ) == NULL )
1549a88394cfSJeff Kirsher 			break;
1550a88394cfSJeff Kirsher 		rxptr->rx_skb_ptr = skb; /* FIXME (?) */
1551*af114c42SChristophe JAILLET 		rxptr->rdes2 = cpu_to_le32(dma_map_single(&db->pdev->dev, skb->data,
1552*af114c42SChristophe JAILLET 							  RX_ALLOC_SIZE, DMA_FROM_DEVICE));
1553a88394cfSJeff Kirsher 		wmb();
1554a88394cfSJeff Kirsher 		rxptr->rdes0 = cpu_to_le32(0x80000000);
1555a88394cfSJeff Kirsher 		rxptr = rxptr->next_rx_desc;
1556a88394cfSJeff Kirsher 		db->rx_avail_cnt++;
1557a88394cfSJeff Kirsher 	}
1558a88394cfSJeff Kirsher 
1559a88394cfSJeff Kirsher 	db->rx_insert_ptr = rxptr;
1560a88394cfSJeff Kirsher }
1561a88394cfSJeff Kirsher 
15625820e97aSFrancois Romieu static void srom_clk_write(void __iomem *ioaddr, u32 data)
15635820e97aSFrancois Romieu {
15645820e97aSFrancois Romieu 	static const u32 cmd[] = {
15655820e97aSFrancois Romieu 		CR9_SROM_READ | CR9_SRCS,
15665820e97aSFrancois Romieu 		CR9_SROM_READ | CR9_SRCS | CR9_SRCLK,
15675820e97aSFrancois Romieu 		CR9_SROM_READ | CR9_SRCS
15685820e97aSFrancois Romieu 	};
15695820e97aSFrancois Romieu 	int i;
15705820e97aSFrancois Romieu 
15715820e97aSFrancois Romieu 	for (i = 0; i < ARRAY_SIZE(cmd); i++) {
15725820e97aSFrancois Romieu 		dw32(DCR9, data | cmd[i]);
15735820e97aSFrancois Romieu 		udelay(5);
15745820e97aSFrancois Romieu 	}
15755820e97aSFrancois Romieu }
1576a88394cfSJeff Kirsher 
1577a88394cfSJeff Kirsher /*
1578a88394cfSJeff Kirsher  *	Read one word data from the serial ROM
1579a88394cfSJeff Kirsher  */
15805820e97aSFrancois Romieu static u16 read_srom_word(void __iomem *ioaddr, int offset)
1581a88394cfSJeff Kirsher {
15825820e97aSFrancois Romieu 	u16 srom_data;
1583a88394cfSJeff Kirsher 	int i;
1584a88394cfSJeff Kirsher 
15855820e97aSFrancois Romieu 	dw32(DCR9, CR9_SROM_READ);
15860c204940Sfrançois romieu 	udelay(5);
15875820e97aSFrancois Romieu 	dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
15880c204940Sfrançois romieu 	udelay(5);
1589a88394cfSJeff Kirsher 
1590a88394cfSJeff Kirsher 	/* Send the Read Command 110b */
15915820e97aSFrancois Romieu 	srom_clk_write(ioaddr, SROM_DATA_1);
15925820e97aSFrancois Romieu 	srom_clk_write(ioaddr, SROM_DATA_1);
15935820e97aSFrancois Romieu 	srom_clk_write(ioaddr, SROM_DATA_0);
1594a88394cfSJeff Kirsher 
1595a88394cfSJeff Kirsher 	/* Send the offset */
1596a88394cfSJeff Kirsher 	for (i = 5; i >= 0; i--) {
1597a88394cfSJeff Kirsher 		srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;
15985820e97aSFrancois Romieu 		srom_clk_write(ioaddr, srom_data);
1599a88394cfSJeff Kirsher 	}
1600a88394cfSJeff Kirsher 
16015820e97aSFrancois Romieu 	dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
16020c204940Sfrançois romieu 	udelay(5);
1603a88394cfSJeff Kirsher 
1604a88394cfSJeff Kirsher 	for (i = 16; i > 0; i--) {
16055820e97aSFrancois Romieu 		dw32(DCR9, CR9_SROM_READ | CR9_SRCS | CR9_SRCLK);
1606a88394cfSJeff Kirsher 		udelay(5);
1607a88394cfSJeff Kirsher 		srom_data = (srom_data << 1) |
16085820e97aSFrancois Romieu 				((dr32(DCR9) & CR9_CRDOUT) ? 1 : 0);
16095820e97aSFrancois Romieu 		dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
1610a88394cfSJeff Kirsher 		udelay(5);
1611a88394cfSJeff Kirsher 	}
1612a88394cfSJeff Kirsher 
16135820e97aSFrancois Romieu 	dw32(DCR9, CR9_SROM_READ);
16140c204940Sfrançois romieu 	udelay(5);
1615a88394cfSJeff Kirsher 	return srom_data;
1616a88394cfSJeff Kirsher }
1617a88394cfSJeff Kirsher 
1618a88394cfSJeff Kirsher 
1619a88394cfSJeff Kirsher /*
1620a88394cfSJeff Kirsher  *	Auto sense the media mode
1621a88394cfSJeff Kirsher  */
1622a88394cfSJeff Kirsher 
1623a88394cfSJeff Kirsher static u8 dmfe_sense_speed(struct dmfe_board_info *db)
1624a88394cfSJeff Kirsher {
16255820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
1626a88394cfSJeff Kirsher 	u8 ErrFlag = 0;
1627a88394cfSJeff Kirsher 	u16 phy_mode;
1628a88394cfSJeff Kirsher 
1629a88394cfSJeff Kirsher 	/* CR6 bit18=0, select 10/100M */
16305820e97aSFrancois Romieu 	update_cr6(db->cr6_data & ~0x40000, ioaddr);
1631a88394cfSJeff Kirsher 
163273852b2bSDavid S. Miller 	phy_mode = dmfe_phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
163373852b2bSDavid S. Miller 	phy_mode = dmfe_phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
1634a88394cfSJeff Kirsher 
1635a88394cfSJeff Kirsher 	if ( (phy_mode & 0x24) == 0x24 ) {
1636a88394cfSJeff Kirsher 		if (db->chip_id == PCI_DM9132_ID)	/* DM9132 */
163773852b2bSDavid S. Miller 			phy_mode = dmfe_phy_read(db->ioaddr,
1638a88394cfSJeff Kirsher 						 db->phy_addr, 7, db->chip_id) & 0xf000;
1639a88394cfSJeff Kirsher 		else 				/* DM9102/DM9102A */
164073852b2bSDavid S. Miller 			phy_mode = dmfe_phy_read(db->ioaddr,
1641a88394cfSJeff Kirsher 						 db->phy_addr, 17, db->chip_id) & 0xf000;
1642a88394cfSJeff Kirsher 		switch (phy_mode) {
1643a88394cfSJeff Kirsher 		case 0x1000: db->op_mode = DMFE_10MHF; break;
1644a88394cfSJeff Kirsher 		case 0x2000: db->op_mode = DMFE_10MFD; break;
1645a88394cfSJeff Kirsher 		case 0x4000: db->op_mode = DMFE_100MHF; break;
1646a88394cfSJeff Kirsher 		case 0x8000: db->op_mode = DMFE_100MFD; break;
1647a88394cfSJeff Kirsher 		default: db->op_mode = DMFE_10MHF;
1648a88394cfSJeff Kirsher 			ErrFlag = 1;
1649a88394cfSJeff Kirsher 			break;
1650a88394cfSJeff Kirsher 		}
1651a88394cfSJeff Kirsher 	} else {
1652a88394cfSJeff Kirsher 		db->op_mode = DMFE_10MHF;
1653a88394cfSJeff Kirsher 		DMFE_DBUG(0, "Link Failed :", phy_mode);
1654a88394cfSJeff Kirsher 		ErrFlag = 1;
1655a88394cfSJeff Kirsher 	}
1656a88394cfSJeff Kirsher 
1657a88394cfSJeff Kirsher 	return ErrFlag;
1658a88394cfSJeff Kirsher }
1659a88394cfSJeff Kirsher 
1660a88394cfSJeff Kirsher 
1661a88394cfSJeff Kirsher /*
1662a88394cfSJeff Kirsher  *	Set 10/100 phyxcer capability
1663a88394cfSJeff Kirsher  *	AUTO mode : phyxcer register4 is NIC capability
1664a88394cfSJeff Kirsher  *	Force mode: phyxcer register4 is the force media
1665a88394cfSJeff Kirsher  */
1666a88394cfSJeff Kirsher 
1667a88394cfSJeff Kirsher static void dmfe_set_phyxcer(struct dmfe_board_info *db)
1668a88394cfSJeff Kirsher {
16695820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
1670a88394cfSJeff Kirsher 	u16 phy_reg;
1671a88394cfSJeff Kirsher 
1672a88394cfSJeff Kirsher 	/* Select 10/100M phyxcer */
1673a88394cfSJeff Kirsher 	db->cr6_data &= ~0x40000;
16745820e97aSFrancois Romieu 	update_cr6(db->cr6_data, ioaddr);
1675a88394cfSJeff Kirsher 
1676a88394cfSJeff Kirsher 	/* DM9009 Chip: Phyxcer reg18 bit12=0 */
1677a88394cfSJeff Kirsher 	if (db->chip_id == PCI_DM9009_ID) {
167873852b2bSDavid S. Miller 		phy_reg = dmfe_phy_read(db->ioaddr,
1679a88394cfSJeff Kirsher 					db->phy_addr, 18, db->chip_id) & ~0x1000;
1680a88394cfSJeff Kirsher 
168173852b2bSDavid S. Miller 		dmfe_phy_write(db->ioaddr,
1682a88394cfSJeff Kirsher 			       db->phy_addr, 18, phy_reg, db->chip_id);
1683a88394cfSJeff Kirsher 	}
1684a88394cfSJeff Kirsher 
1685a88394cfSJeff Kirsher 	/* Phyxcer capability setting */
168673852b2bSDavid S. Miller 	phy_reg = dmfe_phy_read(db->ioaddr, db->phy_addr, 4, db->chip_id) & ~0x01e0;
1687a88394cfSJeff Kirsher 
1688a88394cfSJeff Kirsher 	if (db->media_mode & DMFE_AUTO) {
1689a88394cfSJeff Kirsher 		/* AUTO Mode */
1690a88394cfSJeff Kirsher 		phy_reg |= db->PHY_reg4;
1691a88394cfSJeff Kirsher 	} else {
1692a88394cfSJeff Kirsher 		/* Force Mode */
1693a88394cfSJeff Kirsher 		switch(db->media_mode) {
1694a88394cfSJeff Kirsher 		case DMFE_10MHF: phy_reg |= 0x20; break;
1695a88394cfSJeff Kirsher 		case DMFE_10MFD: phy_reg |= 0x40; break;
1696a88394cfSJeff Kirsher 		case DMFE_100MHF: phy_reg |= 0x80; break;
1697a88394cfSJeff Kirsher 		case DMFE_100MFD: phy_reg |= 0x100; break;
1698a88394cfSJeff Kirsher 		}
1699a88394cfSJeff Kirsher 		if (db->chip_id == PCI_DM9009_ID) phy_reg &= 0x61;
1700a88394cfSJeff Kirsher 	}
1701a88394cfSJeff Kirsher 
1702a88394cfSJeff Kirsher   	/* Write new capability to Phyxcer Reg4 */
1703a88394cfSJeff Kirsher 	if ( !(phy_reg & 0x01e0)) {
1704a88394cfSJeff Kirsher 		phy_reg|=db->PHY_reg4;
1705a88394cfSJeff Kirsher 		db->media_mode|=DMFE_AUTO;
1706a88394cfSJeff Kirsher 	}
170773852b2bSDavid S. Miller 	dmfe_phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id);
1708a88394cfSJeff Kirsher 
1709a88394cfSJeff Kirsher  	/* Restart Auto-Negotiation */
1710a88394cfSJeff Kirsher 	if ( db->chip_type && (db->chip_id == PCI_DM9102_ID) )
171173852b2bSDavid S. Miller 		dmfe_phy_write(db->ioaddr, db->phy_addr, 0, 0x1800, db->chip_id);
1712a88394cfSJeff Kirsher 	if ( !db->chip_type )
171373852b2bSDavid S. Miller 		dmfe_phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id);
1714a88394cfSJeff Kirsher }
1715a88394cfSJeff Kirsher 
1716a88394cfSJeff Kirsher 
1717a88394cfSJeff Kirsher /*
1718a88394cfSJeff Kirsher  *	Process op-mode
1719a88394cfSJeff Kirsher  *	AUTO mode : PHY controller in Auto-negotiation Mode
1720a88394cfSJeff Kirsher  *	Force mode: PHY controller in force mode with HUB
1721a88394cfSJeff Kirsher  *			N-way force capability with SWITCH
1722a88394cfSJeff Kirsher  */
1723a88394cfSJeff Kirsher 
1724a88394cfSJeff Kirsher static void dmfe_process_mode(struct dmfe_board_info *db)
1725a88394cfSJeff Kirsher {
1726a88394cfSJeff Kirsher 	u16 phy_reg;
1727a88394cfSJeff Kirsher 
1728a88394cfSJeff Kirsher 	/* Full Duplex Mode Check */
1729a88394cfSJeff Kirsher 	if (db->op_mode & 0x4)
1730a88394cfSJeff Kirsher 		db->cr6_data |= CR6_FDM;	/* Set Full Duplex Bit */
1731a88394cfSJeff Kirsher 	else
1732a88394cfSJeff Kirsher 		db->cr6_data &= ~CR6_FDM;	/* Clear Full Duplex Bit */
1733a88394cfSJeff Kirsher 
1734a88394cfSJeff Kirsher 	/* Transciver Selection */
1735a88394cfSJeff Kirsher 	if (db->op_mode & 0x10)		/* 1M HomePNA */
1736a88394cfSJeff Kirsher 		db->cr6_data |= 0x40000;/* External MII select */
1737a88394cfSJeff Kirsher 	else
1738a88394cfSJeff Kirsher 		db->cr6_data &= ~0x40000;/* Internal 10/100 transciver */
1739a88394cfSJeff Kirsher 
1740a88394cfSJeff Kirsher 	update_cr6(db->cr6_data, db->ioaddr);
1741a88394cfSJeff Kirsher 
1742a88394cfSJeff Kirsher 	/* 10/100M phyxcer force mode need */
1743a88394cfSJeff Kirsher 	if ( !(db->media_mode & 0x18)) {
1744a88394cfSJeff Kirsher 		/* Forece Mode */
174573852b2bSDavid S. Miller 		phy_reg = dmfe_phy_read(db->ioaddr, db->phy_addr, 6, db->chip_id);
1746a88394cfSJeff Kirsher 		if ( !(phy_reg & 0x1) ) {
1747a88394cfSJeff Kirsher 			/* parter without N-Way capability */
1748a88394cfSJeff Kirsher 			phy_reg = 0x0;
1749a88394cfSJeff Kirsher 			switch(db->op_mode) {
1750a88394cfSJeff Kirsher 			case DMFE_10MHF: phy_reg = 0x0; break;
1751a88394cfSJeff Kirsher 			case DMFE_10MFD: phy_reg = 0x100; break;
1752a88394cfSJeff Kirsher 			case DMFE_100MHF: phy_reg = 0x2000; break;
1753a88394cfSJeff Kirsher 			case DMFE_100MFD: phy_reg = 0x2100; break;
1754a88394cfSJeff Kirsher 			}
175573852b2bSDavid S. Miller 			dmfe_phy_write(db->ioaddr,
1756a88394cfSJeff Kirsher 				       db->phy_addr, 0, phy_reg, db->chip_id);
1757a88394cfSJeff Kirsher        			if ( db->chip_type && (db->chip_id == PCI_DM9102_ID) )
1758a88394cfSJeff Kirsher 				mdelay(20);
175973852b2bSDavid S. Miller 			dmfe_phy_write(db->ioaddr,
1760a88394cfSJeff Kirsher 				       db->phy_addr, 0, phy_reg, db->chip_id);
1761a88394cfSJeff Kirsher 		}
1762a88394cfSJeff Kirsher 	}
1763a88394cfSJeff Kirsher }
1764a88394cfSJeff Kirsher 
1765a88394cfSJeff Kirsher 
1766a88394cfSJeff Kirsher /*
1767a88394cfSJeff Kirsher  *	Write a word to Phy register
1768a88394cfSJeff Kirsher  */
1769a88394cfSJeff Kirsher 
177073852b2bSDavid S. Miller static void dmfe_phy_write(void __iomem *ioaddr, u8 phy_addr, u8 offset,
1771a88394cfSJeff Kirsher 			   u16 phy_data, u32 chip_id)
1772a88394cfSJeff Kirsher {
1773a88394cfSJeff Kirsher 	u16 i;
1774a88394cfSJeff Kirsher 
1775a88394cfSJeff Kirsher 	if (chip_id == PCI_DM9132_ID) {
17765820e97aSFrancois Romieu 		dw16(0x80 + offset * 4, phy_data);
1777a88394cfSJeff Kirsher 	} else {
1778a88394cfSJeff Kirsher 		/* DM9102/DM9102A Chip */
1779a88394cfSJeff Kirsher 
1780a88394cfSJeff Kirsher 		/* Send 33 synchronization clock to Phy controller */
1781a88394cfSJeff Kirsher 		for (i = 0; i < 35; i++)
178273852b2bSDavid S. Miller 			dmfe_phy_write_1bit(ioaddr, PHY_DATA_1);
1783a88394cfSJeff Kirsher 
1784a88394cfSJeff Kirsher 		/* Send start command(01) to Phy */
178573852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_0);
178673852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_1);
1787a88394cfSJeff Kirsher 
1788a88394cfSJeff Kirsher 		/* Send write command(01) to Phy */
178973852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_0);
179073852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_1);
1791a88394cfSJeff Kirsher 
1792a88394cfSJeff Kirsher 		/* Send Phy address */
1793a88394cfSJeff Kirsher 		for (i = 0x10; i > 0; i = i >> 1)
179473852b2bSDavid S. Miller 			dmfe_phy_write_1bit(ioaddr,
1795a88394cfSJeff Kirsher 					    phy_addr & i ? PHY_DATA_1 : PHY_DATA_0);
1796a88394cfSJeff Kirsher 
1797a88394cfSJeff Kirsher 		/* Send register address */
1798a88394cfSJeff Kirsher 		for (i = 0x10; i > 0; i = i >> 1)
179973852b2bSDavid S. Miller 			dmfe_phy_write_1bit(ioaddr,
1800a88394cfSJeff Kirsher 					    offset & i ? PHY_DATA_1 : PHY_DATA_0);
1801a88394cfSJeff Kirsher 
1802a88394cfSJeff Kirsher 		/* written trasnition */
180373852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_1);
180473852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_0);
1805a88394cfSJeff Kirsher 
1806a88394cfSJeff Kirsher 		/* Write a word data to PHY controller */
1807a88394cfSJeff Kirsher 		for ( i = 0x8000; i > 0; i >>= 1)
180873852b2bSDavid S. Miller 			dmfe_phy_write_1bit(ioaddr,
1809a88394cfSJeff Kirsher 					    phy_data & i ? PHY_DATA_1 : PHY_DATA_0);
1810a88394cfSJeff Kirsher 	}
1811a88394cfSJeff Kirsher }
1812a88394cfSJeff Kirsher 
1813a88394cfSJeff Kirsher 
1814a88394cfSJeff Kirsher /*
1815a88394cfSJeff Kirsher  *	Read a word data from phy register
1816a88394cfSJeff Kirsher  */
1817a88394cfSJeff Kirsher 
181873852b2bSDavid S. Miller static u16 dmfe_phy_read(void __iomem *ioaddr, u8 phy_addr, u8 offset, u32 chip_id)
1819a88394cfSJeff Kirsher {
1820a88394cfSJeff Kirsher 	int i;
1821a88394cfSJeff Kirsher 	u16 phy_data;
1822a88394cfSJeff Kirsher 
1823a88394cfSJeff Kirsher 	if (chip_id == PCI_DM9132_ID) {
1824a88394cfSJeff Kirsher 		/* DM9132 Chip */
18255820e97aSFrancois Romieu 		phy_data = dr16(0x80 + offset * 4);
1826a88394cfSJeff Kirsher 	} else {
1827a88394cfSJeff Kirsher 		/* DM9102/DM9102A Chip */
1828a88394cfSJeff Kirsher 
1829a88394cfSJeff Kirsher 		/* Send 33 synchronization clock to Phy controller */
1830a88394cfSJeff Kirsher 		for (i = 0; i < 35; i++)
183173852b2bSDavid S. Miller 			dmfe_phy_write_1bit(ioaddr, PHY_DATA_1);
1832a88394cfSJeff Kirsher 
1833a88394cfSJeff Kirsher 		/* Send start command(01) to Phy */
183473852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_0);
183573852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_1);
1836a88394cfSJeff Kirsher 
1837a88394cfSJeff Kirsher 		/* Send read command(10) to Phy */
183873852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_1);
183973852b2bSDavid S. Miller 		dmfe_phy_write_1bit(ioaddr, PHY_DATA_0);
1840a88394cfSJeff Kirsher 
1841a88394cfSJeff Kirsher 		/* Send Phy address */
1842a88394cfSJeff Kirsher 		for (i = 0x10; i > 0; i = i >> 1)
184373852b2bSDavid S. Miller 			dmfe_phy_write_1bit(ioaddr,
1844a88394cfSJeff Kirsher 					    phy_addr & i ? PHY_DATA_1 : PHY_DATA_0);
1845a88394cfSJeff Kirsher 
1846a88394cfSJeff Kirsher 		/* Send register address */
1847a88394cfSJeff Kirsher 		for (i = 0x10; i > 0; i = i >> 1)
184873852b2bSDavid S. Miller 			dmfe_phy_write_1bit(ioaddr,
1849a88394cfSJeff Kirsher 					    offset & i ? PHY_DATA_1 : PHY_DATA_0);
1850a88394cfSJeff Kirsher 
1851a88394cfSJeff Kirsher 		/* Skip transition state */
185273852b2bSDavid S. Miller 		dmfe_phy_read_1bit(ioaddr);
1853a88394cfSJeff Kirsher 
1854a88394cfSJeff Kirsher 		/* read 16bit data */
1855a88394cfSJeff Kirsher 		for (phy_data = 0, i = 0; i < 16; i++) {
1856a88394cfSJeff Kirsher 			phy_data <<= 1;
185773852b2bSDavid S. Miller 			phy_data |= dmfe_phy_read_1bit(ioaddr);
1858a88394cfSJeff Kirsher 		}
1859a88394cfSJeff Kirsher 	}
1860a88394cfSJeff Kirsher 
1861a88394cfSJeff Kirsher 	return phy_data;
1862a88394cfSJeff Kirsher }
1863a88394cfSJeff Kirsher 
1864a88394cfSJeff Kirsher 
1865a88394cfSJeff Kirsher /*
1866a88394cfSJeff Kirsher  *	Write one bit data to Phy Controller
1867a88394cfSJeff Kirsher  */
1868a88394cfSJeff Kirsher 
186973852b2bSDavid S. Miller static void dmfe_phy_write_1bit(void __iomem *ioaddr, u32 phy_data)
1870a88394cfSJeff Kirsher {
18715820e97aSFrancois Romieu 	dw32(DCR9, phy_data);		/* MII Clock Low */
1872a88394cfSJeff Kirsher 	udelay(1);
18735820e97aSFrancois Romieu 	dw32(DCR9, phy_data | MDCLKH);	/* MII Clock High */
1874a88394cfSJeff Kirsher 	udelay(1);
18755820e97aSFrancois Romieu 	dw32(DCR9, phy_data);		/* MII Clock Low */
1876a88394cfSJeff Kirsher 	udelay(1);
1877a88394cfSJeff Kirsher }
1878a88394cfSJeff Kirsher 
1879a88394cfSJeff Kirsher 
1880a88394cfSJeff Kirsher /*
1881a88394cfSJeff Kirsher  *	Read one bit phy data from PHY controller
1882a88394cfSJeff Kirsher  */
1883a88394cfSJeff Kirsher 
188473852b2bSDavid S. Miller static u16 dmfe_phy_read_1bit(void __iomem *ioaddr)
1885a88394cfSJeff Kirsher {
1886a88394cfSJeff Kirsher 	u16 phy_data;
1887a88394cfSJeff Kirsher 
18885820e97aSFrancois Romieu 	dw32(DCR9, 0x50000);
1889a88394cfSJeff Kirsher 	udelay(1);
18905820e97aSFrancois Romieu 	phy_data = (dr32(DCR9) >> 19) & 0x1;
18915820e97aSFrancois Romieu 	dw32(DCR9, 0x40000);
1892a88394cfSJeff Kirsher 	udelay(1);
1893a88394cfSJeff Kirsher 
1894a88394cfSJeff Kirsher 	return phy_data;
1895a88394cfSJeff Kirsher }
1896a88394cfSJeff Kirsher 
1897a88394cfSJeff Kirsher 
1898a88394cfSJeff Kirsher /*
1899a88394cfSJeff Kirsher  *	Parser SROM and media mode
1900a88394cfSJeff Kirsher  */
1901a88394cfSJeff Kirsher 
1902a88394cfSJeff Kirsher static void dmfe_parse_srom(struct dmfe_board_info * db)
1903a88394cfSJeff Kirsher {
1904a88394cfSJeff Kirsher 	char * srom = db->srom;
1905a88394cfSJeff Kirsher 	int dmfe_mode, tmp_reg;
1906a88394cfSJeff Kirsher 
1907a88394cfSJeff Kirsher 	DMFE_DBUG(0, "dmfe_parse_srom() ", 0);
1908a88394cfSJeff Kirsher 
1909a88394cfSJeff Kirsher 	/* Init CR15 */
1910a88394cfSJeff Kirsher 	db->cr15_data = CR15_DEFAULT;
1911a88394cfSJeff Kirsher 
1912a88394cfSJeff Kirsher 	/* Check SROM Version */
1913a88394cfSJeff Kirsher 	if ( ( (int) srom[18] & 0xff) == SROM_V41_CODE) {
1914a88394cfSJeff Kirsher 		/* SROM V4.01 */
1915a88394cfSJeff Kirsher 		/* Get NIC support media mode */
1916a88394cfSJeff Kirsher 		db->NIC_capability = le16_to_cpup((__le16 *) (srom + 34));
1917a88394cfSJeff Kirsher 		db->PHY_reg4 = 0;
1918a88394cfSJeff Kirsher 		for (tmp_reg = 1; tmp_reg < 0x10; tmp_reg <<= 1) {
1919a88394cfSJeff Kirsher 			switch( db->NIC_capability & tmp_reg ) {
1920a88394cfSJeff Kirsher 			case 0x1: db->PHY_reg4 |= 0x0020; break;
1921a88394cfSJeff Kirsher 			case 0x2: db->PHY_reg4 |= 0x0040; break;
1922a88394cfSJeff Kirsher 			case 0x4: db->PHY_reg4 |= 0x0080; break;
1923a88394cfSJeff Kirsher 			case 0x8: db->PHY_reg4 |= 0x0100; break;
1924a88394cfSJeff Kirsher 			}
1925a88394cfSJeff Kirsher 		}
1926a88394cfSJeff Kirsher 
1927a88394cfSJeff Kirsher 		/* Media Mode Force or not check */
1928a88394cfSJeff Kirsher 		dmfe_mode = (le32_to_cpup((__le32 *) (srom + 34)) &
1929a88394cfSJeff Kirsher 			     le32_to_cpup((__le32 *) (srom + 36)));
1930a88394cfSJeff Kirsher 		switch(dmfe_mode) {
1931a88394cfSJeff Kirsher 		case 0x4: dmfe_media_mode = DMFE_100MHF; break;	/* 100MHF */
1932a88394cfSJeff Kirsher 		case 0x2: dmfe_media_mode = DMFE_10MFD; break;	/* 10MFD */
1933a88394cfSJeff Kirsher 		case 0x8: dmfe_media_mode = DMFE_100MFD; break;	/* 100MFD */
1934a88394cfSJeff Kirsher 		case 0x100:
1935a88394cfSJeff Kirsher 		case 0x200: dmfe_media_mode = DMFE_1M_HPNA; break;/* HomePNA */
1936a88394cfSJeff Kirsher 		}
1937a88394cfSJeff Kirsher 
1938a88394cfSJeff Kirsher 		/* Special Function setting */
1939a88394cfSJeff Kirsher 		/* VLAN function */
1940a88394cfSJeff Kirsher 		if ( (SF_mode & 0x1) || (srom[43] & 0x80) )
1941a88394cfSJeff Kirsher 			db->cr15_data |= 0x40;
1942a88394cfSJeff Kirsher 
1943a88394cfSJeff Kirsher 		/* Flow Control */
1944a88394cfSJeff Kirsher 		if ( (SF_mode & 0x2) || (srom[40] & 0x1) )
1945a88394cfSJeff Kirsher 			db->cr15_data |= 0x400;
1946a88394cfSJeff Kirsher 
1947a88394cfSJeff Kirsher 		/* TX pause packet */
1948a88394cfSJeff Kirsher 		if ( (SF_mode & 0x4) || (srom[40] & 0xe) )
1949a88394cfSJeff Kirsher 			db->cr15_data |= 0x9800;
1950a88394cfSJeff Kirsher 	}
1951a88394cfSJeff Kirsher 
1952a88394cfSJeff Kirsher 	/* Parse HPNA parameter */
1953a88394cfSJeff Kirsher 	db->HPNA_command = 1;
1954a88394cfSJeff Kirsher 
1955a88394cfSJeff Kirsher 	/* Accept remote command or not */
1956a88394cfSJeff Kirsher 	if (HPNA_rx_cmd == 0)
1957a88394cfSJeff Kirsher 		db->HPNA_command |= 0x8000;
1958a88394cfSJeff Kirsher 
1959a88394cfSJeff Kirsher 	 /* Issue remote command & operation mode */
1960a88394cfSJeff Kirsher 	if (HPNA_tx_cmd == 1)
1961a88394cfSJeff Kirsher 		switch(HPNA_mode) {	/* Issue Remote Command */
1962a88394cfSJeff Kirsher 		case 0: db->HPNA_command |= 0x0904; break;
1963a88394cfSJeff Kirsher 		case 1: db->HPNA_command |= 0x0a00; break;
1964a88394cfSJeff Kirsher 		case 2: db->HPNA_command |= 0x0506; break;
1965a88394cfSJeff Kirsher 		case 3: db->HPNA_command |= 0x0602; break;
1966a88394cfSJeff Kirsher 		}
1967a88394cfSJeff Kirsher 	else
1968a88394cfSJeff Kirsher 		switch(HPNA_mode) {	/* Don't Issue */
1969a88394cfSJeff Kirsher 		case 0: db->HPNA_command |= 0x0004; break;
1970a88394cfSJeff Kirsher 		case 1: db->HPNA_command |= 0x0000; break;
1971a88394cfSJeff Kirsher 		case 2: db->HPNA_command |= 0x0006; break;
1972a88394cfSJeff Kirsher 		case 3: db->HPNA_command |= 0x0002; break;
1973a88394cfSJeff Kirsher 		}
1974a88394cfSJeff Kirsher 
1975a88394cfSJeff Kirsher 	/* Check DM9801 or DM9802 present or not */
1976a88394cfSJeff Kirsher 	db->HPNA_present = 0;
1977a88394cfSJeff Kirsher 	update_cr6(db->cr6_data | 0x40000, db->ioaddr);
197873852b2bSDavid S. Miller 	tmp_reg = dmfe_phy_read(db->ioaddr, db->phy_addr, 3, db->chip_id);
1979a88394cfSJeff Kirsher 	if ( ( tmp_reg & 0xfff0 ) == 0xb900 ) {
1980a88394cfSJeff Kirsher 		/* DM9801 or DM9802 present */
1981a88394cfSJeff Kirsher 		db->HPNA_timer = 8;
198273852b2bSDavid S. Miller 		if ( dmfe_phy_read(db->ioaddr, db->phy_addr, 31, db->chip_id) == 0x4404) {
1983a88394cfSJeff Kirsher 			/* DM9801 HomeRun */
1984a88394cfSJeff Kirsher 			db->HPNA_present = 1;
1985a88394cfSJeff Kirsher 			dmfe_program_DM9801(db, tmp_reg);
1986a88394cfSJeff Kirsher 		} else {
1987a88394cfSJeff Kirsher 			/* DM9802 LongRun */
1988a88394cfSJeff Kirsher 			db->HPNA_present = 2;
1989a88394cfSJeff Kirsher 			dmfe_program_DM9802(db);
1990a88394cfSJeff Kirsher 		}
1991a88394cfSJeff Kirsher 	}
1992a88394cfSJeff Kirsher 
1993a88394cfSJeff Kirsher }
1994a88394cfSJeff Kirsher 
1995a88394cfSJeff Kirsher 
1996a88394cfSJeff Kirsher /*
1997a88394cfSJeff Kirsher  *	Init HomeRun DM9801
1998a88394cfSJeff Kirsher  */
1999a88394cfSJeff Kirsher 
2000a88394cfSJeff Kirsher static void dmfe_program_DM9801(struct dmfe_board_info * db, int HPNA_rev)
2001a88394cfSJeff Kirsher {
2002a88394cfSJeff Kirsher 	uint reg17, reg25;
2003a88394cfSJeff Kirsher 
2004a88394cfSJeff Kirsher 	if ( !HPNA_NoiseFloor ) HPNA_NoiseFloor = DM9801_NOISE_FLOOR;
2005a88394cfSJeff Kirsher 	switch(HPNA_rev) {
2006a88394cfSJeff Kirsher 	case 0xb900: /* DM9801 E3 */
2007a88394cfSJeff Kirsher 		db->HPNA_command |= 0x1000;
200873852b2bSDavid S. Miller 		reg25 = dmfe_phy_read(db->ioaddr, db->phy_addr, 24, db->chip_id);
2009a88394cfSJeff Kirsher 		reg25 = ( (reg25 + HPNA_NoiseFloor) & 0xff) | 0xf000;
201073852b2bSDavid S. Miller 		reg17 = dmfe_phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id);
2011a88394cfSJeff Kirsher 		break;
2012a88394cfSJeff Kirsher 	case 0xb901: /* DM9801 E4 */
201373852b2bSDavid S. Miller 		reg25 = dmfe_phy_read(db->ioaddr, db->phy_addr, 25, db->chip_id);
2014a88394cfSJeff Kirsher 		reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor;
201573852b2bSDavid S. Miller 		reg17 = dmfe_phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id);
2016a88394cfSJeff Kirsher 		reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor + 3;
2017a88394cfSJeff Kirsher 		break;
2018a88394cfSJeff Kirsher 	case 0xb902: /* DM9801 E5 */
2019a88394cfSJeff Kirsher 	case 0xb903: /* DM9801 E6 */
2020a88394cfSJeff Kirsher 	default:
2021a88394cfSJeff Kirsher 		db->HPNA_command |= 0x1000;
202273852b2bSDavid S. Miller 		reg25 = dmfe_phy_read(db->ioaddr, db->phy_addr, 25, db->chip_id);
2023a88394cfSJeff Kirsher 		reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor - 5;
202473852b2bSDavid S. Miller 		reg17 = dmfe_phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id);
2025a88394cfSJeff Kirsher 		reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor;
2026a88394cfSJeff Kirsher 		break;
2027a88394cfSJeff Kirsher 	}
202873852b2bSDavid S. Miller 	dmfe_phy_write(db->ioaddr, db->phy_addr, 16, db->HPNA_command, db->chip_id);
202973852b2bSDavid S. Miller 	dmfe_phy_write(db->ioaddr, db->phy_addr, 17, reg17, db->chip_id);
203073852b2bSDavid S. Miller 	dmfe_phy_write(db->ioaddr, db->phy_addr, 25, reg25, db->chip_id);
2031a88394cfSJeff Kirsher }
2032a88394cfSJeff Kirsher 
2033a88394cfSJeff Kirsher 
2034a88394cfSJeff Kirsher /*
2035a88394cfSJeff Kirsher  *	Init HomeRun DM9802
2036a88394cfSJeff Kirsher  */
2037a88394cfSJeff Kirsher 
2038a88394cfSJeff Kirsher static void dmfe_program_DM9802(struct dmfe_board_info * db)
2039a88394cfSJeff Kirsher {
2040a88394cfSJeff Kirsher 	uint phy_reg;
2041a88394cfSJeff Kirsher 
2042a88394cfSJeff Kirsher 	if ( !HPNA_NoiseFloor ) HPNA_NoiseFloor = DM9802_NOISE_FLOOR;
204373852b2bSDavid S. Miller 	dmfe_phy_write(db->ioaddr, db->phy_addr, 16, db->HPNA_command, db->chip_id);
204473852b2bSDavid S. Miller 	phy_reg = dmfe_phy_read(db->ioaddr, db->phy_addr, 25, db->chip_id);
2045a88394cfSJeff Kirsher 	phy_reg = ( phy_reg & 0xff00) + HPNA_NoiseFloor;
204673852b2bSDavid S. Miller 	dmfe_phy_write(db->ioaddr, db->phy_addr, 25, phy_reg, db->chip_id);
2047a88394cfSJeff Kirsher }
2048a88394cfSJeff Kirsher 
2049a88394cfSJeff Kirsher 
2050a88394cfSJeff Kirsher /*
2051a88394cfSJeff Kirsher  *	Check remote HPNA power and speed status. If not correct,
2052a88394cfSJeff Kirsher  *	issue command again.
2053a88394cfSJeff Kirsher */
2054a88394cfSJeff Kirsher 
2055a88394cfSJeff Kirsher static void dmfe_HPNA_remote_cmd_chk(struct dmfe_board_info * db)
2056a88394cfSJeff Kirsher {
2057a88394cfSJeff Kirsher 	uint phy_reg;
2058a88394cfSJeff Kirsher 
2059a88394cfSJeff Kirsher 	/* Got remote device status */
206073852b2bSDavid S. Miller 	phy_reg = dmfe_phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id) & 0x60;
2061a88394cfSJeff Kirsher 	switch(phy_reg) {
2062a88394cfSJeff Kirsher 	case 0x00: phy_reg = 0x0a00;break; /* LP/LS */
2063a88394cfSJeff Kirsher 	case 0x20: phy_reg = 0x0900;break; /* LP/HS */
2064a88394cfSJeff Kirsher 	case 0x40: phy_reg = 0x0600;break; /* HP/LS */
2065a88394cfSJeff Kirsher 	case 0x60: phy_reg = 0x0500;break; /* HP/HS */
2066a88394cfSJeff Kirsher 	}
2067a88394cfSJeff Kirsher 
2068a88394cfSJeff Kirsher 	/* Check remote device status match our setting ot not */
2069a88394cfSJeff Kirsher 	if ( phy_reg != (db->HPNA_command & 0x0f00) ) {
207073852b2bSDavid S. Miller 		dmfe_phy_write(db->ioaddr, db->phy_addr, 16, db->HPNA_command,
2071a88394cfSJeff Kirsher 			       db->chip_id);
2072a88394cfSJeff Kirsher 		db->HPNA_timer=8;
2073a88394cfSJeff Kirsher 	} else
2074a88394cfSJeff Kirsher 		db->HPNA_timer=600;	/* Match, every 10 minutes, check */
2075a88394cfSJeff Kirsher }
2076a88394cfSJeff Kirsher 
2077a88394cfSJeff Kirsher 
2078a88394cfSJeff Kirsher 
20799baa3c34SBenoit Taine static const struct pci_device_id dmfe_pci_tbl[] = {
2080a88394cfSJeff Kirsher 	{ 0x1282, 0x9132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9132_ID },
2081a88394cfSJeff Kirsher 	{ 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9102_ID },
2082a88394cfSJeff Kirsher 	{ 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9100_ID },
2083a88394cfSJeff Kirsher 	{ 0x1282, 0x9009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9009_ID },
2084a88394cfSJeff Kirsher 	{ 0, }
2085a88394cfSJeff Kirsher };
2086a88394cfSJeff Kirsher MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl);
2087a88394cfSJeff Kirsher 
2088f906d0f9SVaibhav Gupta static int __maybe_unused dmfe_suspend(struct device *dev_d)
2089a88394cfSJeff Kirsher {
2090f906d0f9SVaibhav Gupta 	struct net_device *dev = dev_get_drvdata(dev_d);
2091a88394cfSJeff Kirsher 	struct dmfe_board_info *db = netdev_priv(dev);
20925820e97aSFrancois Romieu 	void __iomem *ioaddr = db->ioaddr;
2093a88394cfSJeff Kirsher 
2094a88394cfSJeff Kirsher 	/* Disable upper layer interface */
2095a88394cfSJeff Kirsher 	netif_device_detach(dev);
2096a88394cfSJeff Kirsher 
2097a88394cfSJeff Kirsher 	/* Disable Tx/Rx */
2098a88394cfSJeff Kirsher 	db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);
20995820e97aSFrancois Romieu 	update_cr6(db->cr6_data, ioaddr);
2100a88394cfSJeff Kirsher 
2101a88394cfSJeff Kirsher 	/* Disable Interrupt */
21025820e97aSFrancois Romieu 	dw32(DCR7, 0);
21035820e97aSFrancois Romieu 	dw32(DCR5, dr32(DCR5));
2104a88394cfSJeff Kirsher 
2105a88394cfSJeff Kirsher 	/* Fre RX buffers */
2106a88394cfSJeff Kirsher 	dmfe_free_rxbuffer(db);
2107a88394cfSJeff Kirsher 
2108a88394cfSJeff Kirsher 	/* Enable WOL */
2109f906d0f9SVaibhav Gupta 	device_wakeup_enable(dev_d);
2110a88394cfSJeff Kirsher 
2111a88394cfSJeff Kirsher 	return 0;
2112a88394cfSJeff Kirsher }
2113a88394cfSJeff Kirsher 
2114f906d0f9SVaibhav Gupta static int __maybe_unused dmfe_resume(struct device *dev_d)
2115a88394cfSJeff Kirsher {
2116f906d0f9SVaibhav Gupta 	struct net_device *dev = dev_get_drvdata(dev_d);
2117a88394cfSJeff Kirsher 
2118a88394cfSJeff Kirsher 	/* Re-initialize DM910X board */
2119a88394cfSJeff Kirsher 	dmfe_init_dm910x(dev);
2120a88394cfSJeff Kirsher 
2121a88394cfSJeff Kirsher 	/* Disable WOL */
2122f906d0f9SVaibhav Gupta 	device_wakeup_disable(dev_d);
2123a88394cfSJeff Kirsher 
2124a88394cfSJeff Kirsher 	/* Restart upper layer interface */
2125a88394cfSJeff Kirsher 	netif_device_attach(dev);
2126a88394cfSJeff Kirsher 
2127a88394cfSJeff Kirsher 	return 0;
2128a88394cfSJeff Kirsher }
2129f906d0f9SVaibhav Gupta 
2130f906d0f9SVaibhav Gupta static SIMPLE_DEV_PM_OPS(dmfe_pm_ops, dmfe_suspend, dmfe_resume);
2131a88394cfSJeff Kirsher 
2132a88394cfSJeff Kirsher static struct pci_driver dmfe_driver = {
2133a88394cfSJeff Kirsher 	.name		= "dmfe",
2134a88394cfSJeff Kirsher 	.id_table	= dmfe_pci_tbl,
2135a88394cfSJeff Kirsher 	.probe		= dmfe_init_one,
2136779c1a85SBill Pemberton 	.remove		= dmfe_remove_one,
2137f906d0f9SVaibhav Gupta 	.driver.pm	= &dmfe_pm_ops,
2138a88394cfSJeff Kirsher };
2139a88394cfSJeff Kirsher 
2140a88394cfSJeff Kirsher MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw");
2141a88394cfSJeff Kirsher MODULE_DESCRIPTION("Davicom DM910X fast ethernet driver");
2142a88394cfSJeff Kirsher MODULE_LICENSE("GPL");
2143a88394cfSJeff Kirsher 
2144a88394cfSJeff Kirsher module_param(debug, int, 0);
2145a88394cfSJeff Kirsher module_param(mode, byte, 0);
2146a88394cfSJeff Kirsher module_param(cr6set, int, 0);
2147a88394cfSJeff Kirsher module_param(chkmode, byte, 0);
2148a88394cfSJeff Kirsher module_param(HPNA_mode, byte, 0);
2149a88394cfSJeff Kirsher module_param(HPNA_rx_cmd, byte, 0);
2150a88394cfSJeff Kirsher module_param(HPNA_tx_cmd, byte, 0);
2151a88394cfSJeff Kirsher module_param(HPNA_NoiseFloor, byte, 0);
2152a88394cfSJeff Kirsher module_param(SF_mode, byte, 0);
2153a88394cfSJeff Kirsher MODULE_PARM_DESC(debug, "Davicom DM9xxx enable debugging (0-1)");
2154a88394cfSJeff Kirsher MODULE_PARM_DESC(mode, "Davicom DM9xxx: "
2155a88394cfSJeff Kirsher 		"Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA");
2156a88394cfSJeff Kirsher 
2157a88394cfSJeff Kirsher MODULE_PARM_DESC(SF_mode, "Davicom DM9xxx special function "
2158a88394cfSJeff Kirsher 		"(bit 0: VLAN, bit 1 Flow Control, bit 2: TX pause packet)");
2159a88394cfSJeff Kirsher 
2160a88394cfSJeff Kirsher /*	Description:
2161a88394cfSJeff Kirsher  *	when user used insmod to add module, system invoked init_module()
2162a88394cfSJeff Kirsher  *	to initialize and register.
2163a88394cfSJeff Kirsher  */
2164a88394cfSJeff Kirsher 
2165a88394cfSJeff Kirsher static int __init dmfe_init_module(void)
2166a88394cfSJeff Kirsher {
2167a88394cfSJeff Kirsher 	int rc;
2168a88394cfSJeff Kirsher 
2169a88394cfSJeff Kirsher 	DMFE_DBUG(0, "init_module() ", debug);
2170a88394cfSJeff Kirsher 
2171a88394cfSJeff Kirsher 	if (debug)
2172a88394cfSJeff Kirsher 		dmfe_debug = debug;	/* set debug flag */
2173a88394cfSJeff Kirsher 	if (cr6set)
2174a88394cfSJeff Kirsher 		dmfe_cr6_user_set = cr6set;
2175a88394cfSJeff Kirsher 
2176a88394cfSJeff Kirsher 	switch (mode) {
2177a88394cfSJeff Kirsher 	case DMFE_10MHF:
2178a88394cfSJeff Kirsher 	case DMFE_100MHF:
2179a88394cfSJeff Kirsher 	case DMFE_10MFD:
2180a88394cfSJeff Kirsher 	case DMFE_100MFD:
2181a88394cfSJeff Kirsher 	case DMFE_1M_HPNA:
2182a88394cfSJeff Kirsher 		dmfe_media_mode = mode;
2183a88394cfSJeff Kirsher 		break;
2184fe06bf3dSNathan Chancellor 	default:
2185fe06bf3dSNathan Chancellor 		dmfe_media_mode = DMFE_AUTO;
2186a88394cfSJeff Kirsher 		break;
2187a88394cfSJeff Kirsher 	}
2188a88394cfSJeff Kirsher 
2189a88394cfSJeff Kirsher 	if (HPNA_mode > 4)
2190a88394cfSJeff Kirsher 		HPNA_mode = 0;		/* Default: LP/HS */
2191a88394cfSJeff Kirsher 	if (HPNA_rx_cmd > 1)
2192a88394cfSJeff Kirsher 		HPNA_rx_cmd = 0;	/* Default: Ignored remote cmd */
2193a88394cfSJeff Kirsher 	if (HPNA_tx_cmd > 1)
2194a88394cfSJeff Kirsher 		HPNA_tx_cmd = 0;	/* Default: Don't issue remote cmd */
2195a88394cfSJeff Kirsher 	if (HPNA_NoiseFloor > 15)
2196a88394cfSJeff Kirsher 		HPNA_NoiseFloor = 0;
2197a88394cfSJeff Kirsher 
2198a88394cfSJeff Kirsher 	rc = pci_register_driver(&dmfe_driver);
2199a88394cfSJeff Kirsher 	if (rc < 0)
2200a88394cfSJeff Kirsher 		return rc;
2201a88394cfSJeff Kirsher 
2202a88394cfSJeff Kirsher 	return 0;
2203a88394cfSJeff Kirsher }
2204a88394cfSJeff Kirsher 
2205a88394cfSJeff Kirsher 
2206a88394cfSJeff Kirsher /*
2207a88394cfSJeff Kirsher  *	Description:
2208a88394cfSJeff Kirsher  *	when user used rmmod to delete module, system invoked clean_module()
2209a88394cfSJeff Kirsher  *	to un-register all registered services.
2210a88394cfSJeff Kirsher  */
2211a88394cfSJeff Kirsher 
2212a88394cfSJeff Kirsher static void __exit dmfe_cleanup_module(void)
2213a88394cfSJeff Kirsher {
2214bbc79751SJulia Lawall 	DMFE_DBUG(0, "dmfe_cleanup_module() ", debug);
2215a88394cfSJeff Kirsher 	pci_unregister_driver(&dmfe_driver);
2216a88394cfSJeff Kirsher }
2217a88394cfSJeff Kirsher 
2218a88394cfSJeff Kirsher module_init(dmfe_init_module);
2219a88394cfSJeff Kirsher module_exit(dmfe_cleanup_module);
2220