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