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