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