Root/target/linux/cns21xx/patches-3.6/106-cns21xx-gec-driver.patch

1--- /dev/null
2+++ b/drivers/net/ethernet/cns21xx/cns21xx_gec_main.c
3@@ -0,0 +1,2464 @@
4+/*
5+ * Copyright (c) 2010-2012 Gabor Juhos <juhosg@openwrt.org>
6+ *
7+ * This driver has been derived from the ethernet driver of the
8+ * Star STR81xx SoC.
9+ * Copyright (c) 2008 Cavium Networks
10+ *
11+ * This file is free software; you can redistribute it and/or modify
12+ * it under the terms of the GNU General Public License, Version 2, as
13+ * published by the Free Software Foundation.
14+ */
15+
16+#include <linux/module.h>
17+#include <linux/kernel.h>
18+#include <linux/bootmem.h>
19+#include <linux/sched.h>
20+#include <linux/types.h>
21+#include <linux/fcntl.h>
22+#include <linux/interrupt.h>
23+#include <linux/ptrace.h>
24+#include <linux/ioport.h>
25+#include <linux/in.h>
26+#include <linux/slab.h>
27+#include <linux/init.h>
28+#include <linux/bitops.h>
29+#include <linux/irq.h>
30+#include <linux/io.h>
31+#include <linux/pci.h>
32+#include <linux/errno.h>
33+#include <linux/delay.h>
34+#include <linux/netdevice.h>
35+#include <linux/etherdevice.h>
36+#include <linux/platform_device.h>
37+#include <linux/skbuff.h>
38+#include <linux/ip.h>
39+#include <linux/if_ether.h>
40+#include <linux/icmp.h>
41+#include <linux/udp.h>
42+#include <linux/tcp.h>
43+#include <linux/if_arp.h>
44+#include <net/arp.h>
45+
46+#include <mach/hardware.h>
47+#include <mach/cns21xx.h>
48+#include <mach/cns21xx_misc.h>
49+#include <mach/cns21xx_powermgmt.h>
50+#include <mach/cns21xx_gec_platform.h>
51+
52+#define DRIVER_NAME "cns21xx-gec"
53+
54+/* VSC8601 and WavePlus Phy are the same */
55+#define CNS21XX_GEC_PHY_ADDR 0
56+
57+#define CNS21XX_GEC_TX_HW_CHECKSUM
58+#define CNS21XX_GEC_RX_HW_CHECKSUM
59+
60+#define CNS21XX_PEND_INT_COUNT 16
61+#define CNS21XX_PEND_INT_TIME 5 /* 5 x 20 usecs */
62+
63+#define MAX_PACKET_LEN 1536
64+
65+#define CNS21XX_GEC_NUM_TXDS 48 /* FIXME: original 64 will cause UDP fail */
66+#define CNS21XX_GEC_NUM_RXDS 64
67+
68+struct cns21xx_gec_mib_info {
69+ u32 mib_rx_ok_pkt;
70+ u64 mib_rx_ok_byte;
71+ u32 mib_rx_runt;
72+ u32 mib_rx_over_size;
73+ u32 mib_rx_no_buffer_drop;
74+ u32 mib_rx_crc_err;
75+ u32 mib_rx_arl_drop;
76+ u32 mib_rx_myvid_drop;
77+ u32 mib_rx_csum_err;
78+ u32 mib_rx_pause_frame;
79+ u32 mib_tx_ok_pkt;
80+ u64 mib_tx_ok_byte;
81+ u32 mib_tx_pause_frame;
82+};
83+
84+/*
85+ * Network Driver, Receive/Send and Initial Buffer Function
86+ */
87+struct cns21xx_gec_txd {
88+ /* 1st 32Bits */
89+ u32 sdp;
90+
91+ /* 2nd 32Bits */
92+ u32 length:16;
93+ u32 reserved0:7;
94+ u32 tco:1;
95+ u32 uco:1;
96+ u32 ico:1;
97+ u32 insv:1;
98+ u32 intr:1;
99+ u32 ls:1;
100+ u32 fs:1;
101+ u32 eor:1;
102+ u32 cown:1;
103+
104+ /* 3rd 32Bits */
105+ u32 vid:12;
106+ u32 cfi:1;
107+ u32 pri:3;
108+ u32 epid:16;
109+
110+ /* 4th 32Bits */
111+ u32 reserved1;
112+} __packed;
113+
114+struct cns21xx_gec_rxd {
115+ /* 1st 32Bits */
116+ u32 sdp;
117+
118+ /* 2nd 32Bits */
119+ u32 length:16;
120+ u32 l4f:1;
121+ u32 ipf:1;
122+ u32 prot:2;
123+ u32 vted:1;
124+ u32 mymac:1;
125+ u32 hhit:1;
126+ u32 rmc:1;
127+ u32 crce:1;
128+ u32 osize:1;
129+ u32 reserved0:2;
130+ u32 ls:1;
131+ u32 fs:1;
132+ u32 eor:1;
133+ u32 cown:1;
134+
135+ /* 3rd 32Bits */
136+ u32 vid:12;
137+ u32 cfi:1;
138+ u32 pri:3;
139+ u32 epid:16;
140+
141+ /* 4th 32Bits */
142+ u32 reserved1;
143+} __packed;
144+
145+struct cns21xx_gec_ring {
146+ u32 desc_dma;
147+ void *desc_cpu;
148+ u32 curr;
149+ u32 dirty;
150+ u32 count;
151+ struct sk_buff **skbs;
152+};
153+
154+#define CNS21XX_GEC_NUM_VLANS 4
155+struct cns21xx_gec_vlan {
156+ u32 vid; /* 0~4095 */
157+ u32 control; /* ENABLE or DISABLE */
158+};
159+
160+/* store this information for the driver.. */
161+struct cns21xx_gec {
162+ struct napi_struct napi;
163+ struct net_device *netdev;
164+ struct device *parent;
165+ struct cns21xx_gec_ring txring;
166+ struct cns21xx_gec_ring rxring;
167+
168+ void __iomem *base;
169+ struct resource *mem_res;
170+ struct cns21xx_gec_plat_data *pdata;
171+ spinlock_t lock;
172+ spinlock_t tx_lock;
173+
174+ int status_irq;
175+ int rxrc_irq;
176+ int rxqf_irq;
177+ int txtc_irq;
178+ int txqe_irq;
179+ unsigned long rx_queue_full;
180+
181+ struct cns21xx_gec_vlan vlans[CNS21XX_GEC_NUM_VLANS];
182+
183+ struct timer_list internal_phy_timer;
184+ struct timer_list nic_timer;
185+ u8 phy_addr;
186+ u16 phy_id;
187+ struct cns21xx_gec_mib_info mib_info;
188+};
189+
190+#define GEC_REG_PHY_CTRL0 0x000
191+#define GEC_REG_PHY_CTRL1 0x004
192+#define GEC_REG_MAC_CFG 0x008
193+#define GEC_REG_FC_CFG 0x00c
194+#define GEC_REG_ARL_CFG 0x010
195+#define GEC_REG_MY_MAC_H 0x014
196+#define GEC_REG_MY_MAC_L 0x018
197+#define GEC_REG_HASH_CTRL 0x01c
198+#define GEC_REG_VLAN_CTRL 0x020
199+#define GEC_REG_VLAN_ID_0_1 0x024
200+#define GEC_REG_VLAN_ID_2_3 0x028
201+#define GEC_REG_DMA_CFG 0x030
202+#define GEC_REG_TX_DMA_CTRL 0x034
203+#define GEC_REG_RX_DMA_CTRL 0x038
204+#define GEC_REG_TX_DPTR 0x03c
205+#define GEC_REG_RX_DPTR 0x040
206+#define GEC_REG_TX_BASE_ADDR 0x044
207+#define GEC_REG_RX_BASE_ADDR 0x048
208+#define GEC_REG_DLY_INT_CFG 0x04c
209+#define GEC_REG_INT 0x050
210+#define GEC_REG_INT_MASK 0x054
211+#define GEC_REG_TEST0 0x058
212+#define GEC_REG_TEST1 0x05c
213+#define GEC_REG_EXTEND_CFG 0x060
214+
215+#define GEC_REG_RX_OK_PKT_CNTR 0x100
216+#define GEC_REG_RX_OK_BYTE_CNTR 0x104
217+#define GEC_REG_RX_RUNT_BYTE_CNTR 0x108
218+#define GEC_REG_RX_OSIZE_DROP_PKT_CNTR 0x10c
219+#define GEC_REG_RX_NO_BUF_DROP_PKT_CNTR 0x110
220+#define GEC_REG_RX_CRC_ERR_PKT_CNTR 0x114
221+#define GEC_REG_RX_ARL_DROP_PKT_CNTR 0x118
222+#define GEC_REG_MYVLANID_MISMATCH_DROP_PKT_CNTR 0x11c
223+#define GEC_REG_RX_CHKSUM_ERR_PKT_CNTR 0x120
224+#define GEC_REG_RX_PAUSE_FRAME_PKT_CNTR 0x124
225+#define GEC_REG_TX_OK_PKT_CNTR 0x128
226+#define GEC_REG_TX_OK_BYTE_CNTR 0x12c
227+#define GEC_REG_TX_COLLISION_CNTR 0x130
228+#define GEC_REG_TX_PAUSE_FRAME_CNTR 0x130
229+#define GEC_REG_TX_FIFO_UNDERRUN_RETX_CNTR 0x134
230+
231+#define GEC_INT_MIB_COUNTER_TH BIT(3)
232+#define GEC_INT_PORT_STATUS_CHG BIT(2)
233+
234+#define FE_PHY_LED_MODE (0x1 << 12)
235+
236+static void internal_phy_init_timer(struct cns21xx_gec *gec);
237+static void internal_phy_start_timer(struct cns21xx_gec *gec);
238+static void internal_phy_stop_timer(struct cns21xx_gec *gec);
239+
240+static void cns21xx_gec_phy_powerdown(struct cns21xx_gec *gec);
241+static void cns21xx_gec_phy_powerup(struct cns21xx_gec *gec);
242+
243+static inline u32 cns21xx_gec_rr(struct cns21xx_gec *gec, unsigned int reg)
244+{
245+ return __raw_readl(gec->base + reg);
246+}
247+
248+static inline void cns21xx_gec_wr(struct cns21xx_gec *gec, unsigned int reg,
249+ u32 val)
250+{
251+ __raw_writel(val, gec->base + reg);
252+}
253+
254+static void cns21xx_gec_timer_func(unsigned long data)
255+{
256+ struct cns21xx_gec *gec = (struct cns21xx_gec *) data;
257+ struct cns21xx_gec_ring *txring = &gec->txring;
258+ int i;
259+ int txsd_index;
260+ int txsd_current;
261+ int skb_free_count = 0;
262+ struct cns21xx_gec_txd *txd;
263+ unsigned long flags;
264+
265+ local_irq_save(flags);
266+ txsd_current = cns21xx_gec_rr(gec, GEC_REG_TX_DPTR);
267+ txsd_index = (txsd_current - (u32)txring->desc_dma) >> 4;
268+ if (txsd_index > txring->dirty) {
269+ skb_free_count = txsd_index - txring->dirty;
270+ } else if (txsd_index <= txring->dirty) {
271+ skb_free_count = txring->count + txsd_index -
272+ txring->dirty;
273+ }
274+ for (i = 0; i < skb_free_count; i++) {
275+ txd = ((struct cns21xx_gec_txd *) txring->desc_cpu) +
276+ txring->dirty;
277+
278+ if (txd->cown == 0)
279+ break;
280+
281+ if (txring->skbs[txring->dirty]) {
282+ dev_kfree_skb_any(txring->skbs[txring->dirty]);
283+ txring->skbs[txring->dirty] = NULL;
284+
285+ dma_unmap_single(gec->parent,
286+ txd->sdp,
287+ txd->length,
288+ DMA_TO_DEVICE);
289+ }
290+
291+ txring->dirty++;
292+ if (txring->dirty == txring->count)
293+ txring->dirty = 0;
294+ }
295+ local_irq_restore(flags);
296+}
297+
298+static void __init cns21xx_gec_timer_init(struct cns21xx_gec *gec)
299+{
300+ init_timer(&gec->nic_timer);
301+ gec->nic_timer.function = &cns21xx_gec_timer_func;
302+ gec->nic_timer.data = (unsigned long) gec;
303+}
304+
305+static void cns21xx_gec_timer_modify(struct cns21xx_gec *gec, unsigned int t)
306+{
307+ mod_timer(&gec->nic_timer, jiffies + t);
308+}
309+
310+static int cns21xx_gec_write_phy(struct cns21xx_gec *gec,
311+ u8 addr, u8 reg, u16 val)
312+{
313+ int i;
314+
315+ if (addr > 31 || reg > 31)
316+ return -EINVAL;
317+
318+ /* clear previous rw_ok status */
319+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL0, 0x1 << 15);
320+
321+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL0,
322+ addr | (reg << 8) | (val << 16) | (0x1 << 13));
323+
324+ for (i = 0; i < 10000; i++) {
325+ u32 status;
326+
327+ status = cns21xx_gec_rr(gec, GEC_REG_PHY_CTRL0);
328+ if (status & (0x1 << 15)) {
329+ /*
330+ * clear the rw_ok status,
331+ * and clear other bits value
332+ */
333+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL0, (0x1 << 15));
334+ return 0;
335+ }
336+ udelay(1000);
337+ }
338+
339+ dev_err(&gec->netdev->dev,
340+ "%s timed out, phy_addr:0x%x, phy_reg:0x%x, write_data:0x%x\n",
341+ __func__, addr, reg, val);
342+
343+ return -EIO;
344+}
345+
346+static int cns21xx_gec_read_phy(struct cns21xx_gec *gec,
347+ u8 addr, u8 reg, u16 *val)
348+{
349+ int i;
350+
351+ if (addr > 31 || reg > 31)
352+ return -EINVAL;
353+
354+ /* clear previous rw_ok status */
355+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL0, 0x1 << 15);
356+
357+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL0,
358+ addr | (reg << 8) | (0x1 << 14));
359+
360+ for (i = 0; i < 10000; i++) {
361+ u32 status;
362+
363+ status = cns21xx_gec_rr(gec, GEC_REG_PHY_CTRL0);
364+ if (status & (0x1 << 15)) {
365+ /*
366+ * clear the rw_ok status,
367+ * and clear other bits value
368+ */
369+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL0, (0x1 << 15));
370+ *val = (status >> 16) & 0xffff;
371+ return 0;
372+ }
373+ udelay(1000);
374+ }
375+
376+ dev_err(&gec->netdev->dev,
377+ "%s timed out, phy_addr:0x%x, phy_reg:0x%x\n",
378+ __func__, addr, reg);
379+
380+ *val = 0xffff;
381+ return -EIO;
382+}
383+
384+static void cns21xx_gec_dma_config(struct cns21xx_gec *gec)
385+{
386+ u32 dma_config = 0;
387+
388+ dma_config = cns21xx_gec_rr(gec, GEC_REG_DMA_CFG);
389+
390+ /* Config TX DMA */
391+ /* TX auto polling: 1 us */
392+ dma_config &= ~(0x3 << 6);
393+ /* TX auto polling :100us */
394+ dma_config |= (0x2 << 6);
395+ /* TX auto polling C-bit enable */
396+ dma_config |= (0x1 << 5);
397+ /* TX can transmit packets, No suspend */
398+ dma_config &= ~(0x1 << 4);
399+
400+ /* Config RX DMA */
401+ /* RX auto polling: 1 us */
402+ dma_config &= ~(0x3 << 2);
403+ /* RX auto polling :100us */
404+ dma_config |= (0x2 << 2);
405+ /* RX auto polling C-bit enable */
406+ dma_config |= (0x1 << 1);
407+ /* RX can receive packets, No suspend */
408+ dma_config &= ~0x1;
409+
410+ /* 4N+2(for Linux) */
411+ dma_config &= ~(0x1 << 16);
412+
413+ cns21xx_gec_wr(gec, GEC_REG_DMA_CFG, dma_config);
414+}
415+
416+static void cns21xx_gec_mac_config(struct cns21xx_gec *gec)
417+{
418+ u32 mac_config;
419+
420+ mac_config = cns21xx_gec_rr(gec, GEC_REG_MAC_CFG);
421+
422+#ifdef CNS21XX_GEC_TX_HW_CHECKSUM
423+ /* Tx ChkSum offload On: TCP/UDP/IP */
424+ mac_config |= (0x1 << 26);
425+#else
426+ /* Tx ChkSum offload Off: TCP/UDP/IP */
427+ mac_config &= ~(0x1 << 26);
428+#endif
429+
430+#ifdef CNS21XX_GEC_RX_HW_CHECKSUM
431+ /* Rx ChkSum offload On: TCP/UDP/IP */
432+ mac_config |= (0x1 << 25);
433+#else
434+ /* Rx ChkSum offload Off: TCP/UDP/IP */
435+ mac_config &= ~(0x1 << 25);
436+#endif
437+
438+ /* Accept CSUM error pkt */
439+ mac_config |= (0x1 << 24);
440+ /* IST disable */
441+ mac_config &= ~(0x1 << 23);
442+ /* Strip vlan tag */
443+ mac_config |= (0x1 << 22);
444+ /* Accept CRC error pkt */
445+ mac_config |= (0x1 << 21);
446+ /* CRC strip */
447+ mac_config |= (0x1 << 20);
448+
449+ /* Discard oversize pkt */
450+ mac_config &= ~(0x1 << 18);
451+
452+ /* clear, set 1518 */
453+ mac_config &= ~(0x3 << 16);
454+
455+ /* 1536 */
456+ mac_config |= (0x2 << 16);
457+
458+ /* IPG */
459+ mac_config |= (0x1f << 10);
460+
461+ /* Do not skip 16 consecutive collisions pkt */
462+ /* allow to re-tx */
463+ mac_config |= (0x1 << 9);
464+ /* Fast retry */
465+ mac_config |= (0x1 << 8);
466+
467+ cns21xx_gec_wr(gec, GEC_REG_MAC_CFG, mac_config);
468+}
469+
470+static void cns21xx_gec_fc_config(struct cns21xx_gec *gec)
471+{
472+ u32 fc_config;
473+
474+ fc_config = cns21xx_gec_rr(gec, GEC_REG_FC_CFG);
475+
476+ /* Send pause on frame threshold */
477+ /* Clear */
478+ fc_config &= ~(0xfff << 16);
479+ fc_config |= (0x360 << 16);
480+ /* Disable UC_PAUSE */
481+ fc_config &= ~(0x1 << 8);
482+ /* Enable Half Duplex backpressure */
483+ fc_config |= (0x1 << 7);
484+ /* Collision-based BP */
485+ fc_config &= ~(0x1 << 6);
486+ /* Disable max BP collision */
487+ fc_config &= ~(0x1 << 5);
488+ /* Clear */
489+ fc_config &= ~(0x1f);
490+ /* Set */
491+ fc_config |= (0xc);
492+
493+ cns21xx_gec_wr(gec, GEC_REG_FC_CFG, fc_config);
494+}
495+
496+static void cns21xx_gec_internal_phy_config(struct cns21xx_gec *gec)
497+{
498+ u32 phy_ctrl1;
499+ u32 phy_addr;
500+
501+ dev_info(&gec->netdev->dev, "Internal PHY\n");
502+
503+ phy_addr = CNS21XX_GEC_PHY_ADDR;
504+ gec->phy_addr = phy_addr;
505+
506+ phy_ctrl1 = cns21xx_gec_rr(gec, GEC_REG_PHY_CTRL1);
507+
508+ /* set phy addr for auto-polling */
509+ phy_ctrl1 |= (phy_addr & 0x1f) << 24;
510+
511+ /* set internal phy mode */
512+ /* internel 10/100 phy */
513+ phy_ctrl1 |= 0x1 << 18;
514+
515+ /* MII */
516+ phy_ctrl1 &= ~(0x1 << 17);
517+
518+ /* MAC mode */
519+ phy_ctrl1 &= ~(0x1 << 16);
520+
521+ /* config PHY LED bit[13:12] */
522+ cns21xx_gec_read_phy(gec, phy_addr, 31, (u16 *)(&phy_ctrl1));
523+ /* clear LED control */
524+ phy_ctrl1 &= ~(0x3 << 12);
525+ phy_ctrl1 |= FE_PHY_LED_MODE;
526+ cns21xx_gec_write_phy(gec, phy_addr, 31, phy_ctrl1);
527+
528+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL1, phy_ctrl1);
529+}
530+
531+static void cns21xx_gec_vsc8601_phy_config(struct cns21xx_gec *gec)
532+{
533+ u32 phy_ctrl1;
534+ u32 phy_addr;
535+ u16 phy_data;
536+
537+ phy_addr = CNS21XX_GEC_PHY_ADDR;
538+ gec->phy_addr = phy_addr;
539+
540+ phy_ctrl1 = cns21xx_gec_rr(gec, GEC_REG_PHY_CTRL1);
541+
542+ /* phy addr for auto-polling */
543+ phy_ctrl1 |= phy_addr << 24;
544+
545+ /* set external phy mode */
546+ phy_ctrl1 &= ~(0x1 << 18);
547+
548+ /* set RGMII */
549+ phy_ctrl1 |= (0x1 << 17);
550+
551+ /* set MII interface */
552+ phy_ctrl1 &= ~(0x1 << 16);
553+
554+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL1, phy_ctrl1);
555+
556+ /* set phy addr for auto-polling */
557+ phy_ctrl1 |= phy_addr << 24;
558+
559+ /* set external phy mode */
560+ /* MII/RGMII interface */
561+ phy_ctrl1 &= ~(0x1 << 18);
562+
563+ /* RGMII */
564+ phy_ctrl1 |= (0x1 << 17);
565+
566+ /* MAC mode */
567+ phy_ctrl1 &= ~(0x1 << 16);
568+
569+ cns21xx_gec_read_phy(gec, phy_addr, 3, &phy_data);
570+ if ((phy_data & 0x000f) == 0x0000) {
571+ /* type A chip */
572+ u16 tmp16;
573+
574+ dev_info(&gec->netdev->dev, "VSC8601 Type A Chip\n");
575+ cns21xx_gec_write_phy(gec, phy_addr, 31, 0x52B5);
576+ cns21xx_gec_write_phy(gec, phy_addr, 16, 0xAF8A);
577+
578+ phy_data = 0x0;
579+ cns21xx_gec_read_phy(gec, phy_addr, 18, &tmp16);
580+ phy_data |= (tmp16 & ~0x0);
581+ cns21xx_gec_write_phy(gec, phy_addr, 18, phy_data);
582+
583+ phy_data = 0x0008;
584+ cns21xx_gec_read_phy(gec, phy_addr, 17, &tmp16);
585+ phy_data |= (tmp16 & ~0x000C);
586+ cns21xx_gec_write_phy(gec, phy_addr, 17, phy_data);
587+
588+ cns21xx_gec_write_phy(gec, phy_addr, 16, 0x8F8A);
589+ cns21xx_gec_write_phy(gec, phy_addr, 16, 0xAF86);
590+
591+ phy_data = 0x0008;
592+ cns21xx_gec_read_phy(gec, phy_addr, 18, &tmp16);
593+ phy_data |= (tmp16 & ~0x000C);
594+ cns21xx_gec_write_phy(gec, phy_addr, 18, phy_data);
595+
596+ phy_data = 0x0;
597+ cns21xx_gec_read_phy(gec, phy_addr, 17, &tmp16);
598+ phy_data |= (tmp16 & ~0x0);
599+ cns21xx_gec_write_phy(gec, phy_addr, 17, phy_data);
600+
601+ cns21xx_gec_write_phy(gec, phy_addr, 16, 0x8F8A);
602+
603+ cns21xx_gec_write_phy(gec, phy_addr, 16, 0xAF82);
604+
605+ phy_data = 0x0;
606+ cns21xx_gec_read_phy(gec, phy_addr, 18, &tmp16);
607+ phy_data |= (tmp16 & ~0x0);
608+ cns21xx_gec_write_phy(gec, phy_addr, 18, phy_data);
609+
610+ phy_data = 0x0100;
611+ cns21xx_gec_read_phy(gec, phy_addr, 17, &tmp16);
612+ phy_data |= (tmp16 & ~0x0180);
613+ cns21xx_gec_write_phy(gec, phy_addr, 17, phy_data);
614+
615+ cns21xx_gec_write_phy(gec, phy_addr, 16, 0x8F82);
616+
617+ cns21xx_gec_write_phy(gec, phy_addr, 31, 0x0);
618+
619+ /* Set port type: single port */
620+ cns21xx_gec_read_phy(gec, phy_addr, 9, &phy_data);
621+ phy_data &= ~(0x1 << 10);
622+ cns21xx_gec_write_phy(gec, phy_addr, 9, phy_data);
623+ } else if ((phy_data & 0x000f) == 0x0001) {
624+ /* type B chip */
625+ dev_info(&gec->netdev->dev, "VSC8601 Type B Chip\n");
626+
627+ cns21xx_gec_read_phy(gec, phy_addr, 23, &phy_data);
628+ phy_data |= (0x1 << 8); /* set RGMII timing skew */
629+ cns21xx_gec_write_phy(gec, phy_addr, 23, phy_data);
630+ }
631+
632+ /* change to extened registers */
633+ cns21xx_gec_write_phy(gec, phy_addr, 31, 0x0001);
634+
635+ cns21xx_gec_read_phy(gec, phy_addr, 28, &phy_data);
636+ phy_data &= ~(0x3 << 14); /* set RGMII TX timing skew */
637+ phy_data |= (0x3 << 14); /* 2.0ns */
638+ phy_data &= ~(0x3 << 12); /* set RGMII RX timing skew */
639+ phy_data |= (0x3 << 12); /* 2.0ns */
640+ cns21xx_gec_write_phy(gec, phy_addr, 28, phy_data);
641+
642+ /* change to normal registers */
643+ cns21xx_gec_write_phy(gec, phy_addr, 31, 0x0000);
644+
645+#if 0
646+ /* set TX and RX clock skew */
647+ cns21xx_gec_wr(gec, GEC_REG_TEST0, (0x2 << 2) | (0x2 << 0));
648+#endif
649+
650+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL1, phy_ctrl1);
651+}
652+
653+static void cns21xx_gec_ip101a_phy_config(struct cns21xx_gec *gec)
654+{
655+ u32 phy_ctrl1;
656+ u32 phy_addr;
657+
658+ dev_info(&gec->netdev->dev, "ICPlus IP101A\n");
659+
660+ phy_addr = 1;
661+ gec->phy_addr = phy_addr;
662+
663+ phy_ctrl1 = cns21xx_gec_rr(gec, GEC_REG_PHY_CTRL1);
664+
665+ /* set phy addr for auto-polling */
666+ phy_ctrl1 |= phy_addr << 24;
667+
668+ /* set external phy mode */
669+ /* MII/RGMII interface */
670+ phy_ctrl1 &= ~(0x1 << 18);
671+
672+ /* MII */
673+ phy_ctrl1 &= ~(0x1 << 17);
674+
675+ /* MAC mode */
676+ phy_ctrl1 &= ~(0x1 << 16);
677+
678+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL1, phy_ctrl1);
679+}
680+
681+static void cns21xx_gec_ip1001_phy_config(struct cns21xx_gec *gec)
682+{
683+ u32 phy_ctrl1;
684+ u32 phy_addr;
685+ u16 phy_data;
686+
687+ dev_info(&gec->netdev->dev, "ICPlus IP1001\n");
688+
689+ phy_addr = 1;
690+ gec->phy_addr = phy_addr;
691+
692+ phy_ctrl1 = cns21xx_gec_rr(gec, GEC_REG_PHY_CTRL1);
693+
694+ /* set phy addr for auto-polling */
695+ phy_ctrl1 |= phy_addr << 24;
696+
697+ /* set external phy mode */
698+ /* MII/RGMII interface */
699+ phy_ctrl1 &= ~(0x1 << 18);
700+
701+ /* RGMII */
702+ phy_ctrl1 |= (0x1 << 17);
703+
704+ /* MAC mode */
705+ phy_ctrl1 &= ~(0x1 << 16);
706+
707+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL1, phy_ctrl1);
708+ cns21xx_gec_read_phy(gec, phy_addr, 2, &phy_data);
709+
710+ /* set AN capability */
711+ cns21xx_gec_read_phy(gec, phy_addr, 4, &phy_data);
712+ /* clear existing values */
713+ phy_data &= ~(0xf << 5);
714+ /* 10Half */
715+ phy_data |= (0x1 << 5);
716+ /* 10Full */
717+ phy_data |= (0x1 << 6);
718+ /* 100Half */
719+ phy_data |= (0x1 << 7);
720+ /* 100Full */
721+ phy_data |= (0x1 << 8);
722+ /* FC on */
723+ phy_data |= (0x1 << 10);
724+ cns21xx_gec_write_phy(gec, phy_addr, 4, phy_data);
725+
726+ cns21xx_gec_read_phy(gec, phy_addr, 9, &phy_data);
727+ /* 1000Full on */
728+ phy_data |= (0x1 << 9);
729+ phy_data &= ~(0x1 << 10);
730+ phy_data |= (0x1 << 12);
731+ cns21xx_gec_write_phy(gec, phy_addr, 9, phy_data);
732+
733+ cns21xx_gec_read_phy(gec, phy_addr, 16, &phy_data);
734+ /* Smart function off */
735+ phy_data &= ~(0x1 << 11);
736+ /* TX delay */
737+ phy_data |= (0x1 << 0);
738+ /* RX delay */
739+ phy_data |= (0x1 << 1);
740+ cns21xx_gec_write_phy(gec, phy_addr, 16, phy_data);
741+
742+ cns21xx_gec_read_phy(gec, phy_addr, 16, &phy_data);
743+
744+#if 0
745+ cns21xx_gec_read_phy(gec, phy_addr, 20, &phy_data);
746+ phy_data &= ~(0x1<<2);
747+
748+ phy_data |= (0x1<<9);
749+ cns21xx_gec_write_phy(gec, phy_addr, 20, phy_data);
750+#endif
751+
752+ cns21xx_gec_read_phy(gec, phy_addr, 0, &phy_data);
753+ phy_data |= (0x1 << 9); /* re-AN */
754+ cns21xx_gec_write_phy(gec, phy_addr, 0, phy_data);
755+
756+ cns21xx_gec_read_phy(gec, phy_addr, 9, &phy_data);
757+
758+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL1, phy_ctrl1);
759+}
760+
761+static int cns21xx_gec_phy_config(struct cns21xx_gec *gec)
762+{
763+ u32 phy_ctrl1;
764+
765+ switch (gec->pdata->phy_type) {
766+ case CNS21XX_GEC_PHY_TYPE_INTERNAL:
767+ cns21xx_gec_internal_phy_config(gec);
768+ break;
769+
770+ case CNS21XX_GEC_PHY_TYPE_VSC8601:
771+ cns21xx_gec_vsc8601_phy_config(gec);
772+ break;
773+
774+ case CNS21XX_GEC_PHY_TYPE_IP101A:
775+ cns21xx_gec_ip101a_phy_config(gec);
776+ break;
777+
778+ case CNS21XX_GEC_PHY_TYPE_IP1001:
779+ cns21xx_gec_ip1001_phy_config(gec);
780+ break;
781+
782+ default:
783+ return -EINVAL;
784+ }
785+
786+ phy_ctrl1 = cns21xx_gec_rr(gec, GEC_REG_PHY_CTRL1);
787+
788+ /* AN On */
789+ phy_ctrl1 |= (0x1 << 8);
790+ if (!((phy_ctrl1 >> 8) & 0x1)) { /* AN disable */
791+ /* Force to FullDuplex mode */
792+ phy_ctrl1 &= ~(0x1 << 11); /* Half */
793+
794+ /* Force to 100Mbps mode */
795+ phy_ctrl1 &= ~(0x3 << 9); /* clear to 10M */
796+ phy_ctrl1 |= (0x1 << 9); /* set to 100M */
797+ }
798+
799+ /* Force TX FlowCtrl On,in 1000M */
800+ phy_ctrl1 |= (0x1 << 13);
801+
802+ /* Force TX FlowCtrl On, in 10/100M */
803+ phy_ctrl1 |= (0x1 << 12);
804+
805+ /* Enable MII auto polling */
806+ phy_ctrl1 &= ~(0x1 << 7);
807+
808+ cns21xx_gec_wr(gec, GEC_REG_PHY_CTRL1, phy_ctrl1);
809+ cns21xx_gec_phy_powerdown(gec);
810+
811+ return 0;
812+}
813+
814+static void cns21xx_gec_vlan_config(struct cns21xx_gec *gec)
815+{
816+ /* setup VLAN entries */
817+ gec->vlans[0].vid = 2;
818+ gec->vlans[0].control = 0;
819+ gec->vlans[1].vid = 2;
820+ gec->vlans[1].control = 1;
821+ gec->vlans[2].vid = 1;
822+ gec->vlans[2].control = 1;
823+ gec->vlans[3].vid = 1;
824+ gec->vlans[3].control = 0;
825+
826+ cns21xx_gec_wr(gec, GEC_REG_VLAN_ID_0_1,
827+ (gec->vlans[0].vid & 0x0fff) |
828+ ((gec->vlans[1].vid & 0x0fff) << 16));
829+
830+ cns21xx_gec_wr(gec, GEC_REG_VLAN_ID_2_3,
831+ (gec->vlans[2].vid & 0x0fff) |
832+ ((gec->vlans[3].vid & 0x0fff) << 16));
833+
834+ cns21xx_gec_wr(gec, GEC_REG_VLAN_CTRL,
835+ (gec->vlans[0].control << 0) |
836+ (gec->vlans[1].control << 1) |
837+ (gec->vlans[2].control << 2) |
838+ (gec->vlans[3].control << 3));
839+}
840+
841+static int cns21xx_gec_arl_config(struct cns21xx_gec *gec)
842+{
843+ u32 arl_config;
844+
845+ arl_config = cns21xx_gec_rr(gec, GEC_REG_ARL_CFG);
846+
847+ /* Misc Mode ON */
848+ arl_config |= (0x1 << 4);
849+
850+ /* My MAC only enable */
851+ arl_config |= (0x1 << 3);
852+
853+ /* Learn SA On */
854+ arl_config &= ~(0x1 << 2);
855+
856+ /* Forward MC to CPU */
857+ arl_config &= ~(0x1 << 1);
858+
859+ /* Hash direct mode */
860+ arl_config &= ~(0x1);
861+
862+ cns21xx_gec_wr(gec, GEC_REG_ARL_CFG, arl_config);
863+
864+ return 0;
865+}
866+
867+static void cns21xx_gec_phy_powerdown(struct cns21xx_gec *gec)
868+{
869+ u16 phy_data = 0;
870+
871+ cns21xx_gec_read_phy(gec, gec->phy_addr, 0, &phy_data);
872+ phy_data |= (0x1 << 11);
873+ cns21xx_gec_write_phy(gec, gec->phy_addr, 0, phy_data);
874+
875+ PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
876+ PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << 15);
877+}
878+
879+static void cns21xx_gec_phy_powerup(struct cns21xx_gec *gec)
880+{
881+ u16 phy_data = 0;
882+
883+ cns21xx_gec_read_phy(gec, gec->phy_addr, 0, &phy_data);
884+ phy_data &= ~(0x1 << 11);
885+ cns21xx_gec_write_phy(gec, gec->phy_addr, 0, phy_data);
886+
887+ PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
888+}
889+
890+static void cns21xx_gec_enable(struct cns21xx_gec *gec)
891+{
892+ /* start Rx DMA */
893+ cns21xx_gec_wr(gec, GEC_REG_RX_DMA_CTRL, 1);
894+
895+ cns21xx_gec_phy_powerup(gec);
896+ internal_phy_start_timer(gec);
897+}
898+
899+static void cns21xx_gec_shutdown(struct cns21xx_gec *gec)
900+{
901+ /* stop Rx and Tx DMA */
902+ cns21xx_gec_wr(gec, GEC_REG_RX_DMA_CTRL, 0);
903+ cns21xx_gec_wr(gec, GEC_REG_TX_DMA_CTRL, 0);
904+
905+ internal_phy_stop_timer(gec);
906+}
907+
908+static irqreturn_t cns21xx_gec_receive_isr(int irq, void *dev_id)
909+{
910+ struct cns21xx_gec *gec = dev_id;
911+
912+ if (!test_bit(NAPI_STATE_SCHED, &gec->napi.state)) {
913+ if (likely(napi_schedule_prep(&gec->napi)))
914+ __napi_schedule(&gec->napi);
915+ }
916+
917+ return IRQ_HANDLED;
918+}
919+
920+static int cns21xx_gec_install_receive_isr(struct cns21xx_gec *gec)
921+{
922+ int err;
923+
924+ err = request_irq(gec->rxrc_irq, cns21xx_gec_receive_isr,
925+ IRQF_SHARED, dev_name(&gec->netdev->dev), gec);
926+ if (err)
927+ dev_err(&gec->netdev->dev,
928+ "unable to get IRQ %d (err=%d)\n",
929+ gec->rxrc_irq, err);
930+
931+ return err;
932+}
933+
934+static void cns21xx_gec_uninstall_receive_isr(struct cns21xx_gec *gec)
935+{
936+ free_irq(gec->rxrc_irq, gec);
937+}
938+
939+static irqreturn_t cns21xx_gec_rxqf_isr(int irq, void *dev_id)
940+{
941+ struct cns21xx_gec *gec = dev_id;
942+
943+ /*
944+ * because in normal state, fsql only invoke once
945+ * and set_bit is atomic function, so don't mask it
946+ */
947+ set_bit(0, &gec->rx_queue_full);
948+ if (!test_bit(NAPI_STATE_SCHED, &gec->napi.state)) {
949+ if (likely(napi_schedule_prep(&gec->napi)))
950+ __napi_schedule(&gec->napi);
951+ }
952+
953+ return IRQ_HANDLED;
954+}
955+
956+static int cns21xx_gec_install_rxqf_isr(struct cns21xx_gec *gec)
957+{
958+ int err;
959+
960+ /* QUEUE full interrupt handler */
961+ err = request_irq(gec->rxqf_irq, cns21xx_gec_rxqf_isr,
962+ IRQF_SHARED, dev_name(&gec->netdev->dev), gec);
963+ if (err)
964+ dev_err(&gec->netdev->dev,
965+ "unable to get IRQ %d (err=%d)\n",
966+ gec->rxqf_irq, err);
967+
968+ return err;
969+}
970+
971+static void cns21xx_gec_uninstall_rxqf_isr(struct cns21xx_gec *gec)
972+{
973+ free_irq(gec->rxqf_irq, gec);
974+}
975+
976+static void cns21xx_gec_mib_reset(struct cns21xx_gec *gec)
977+{
978+ unsigned long flags;
979+
980+ local_irq_save(flags);
981+ (void) cns21xx_gec_rr(gec, GEC_REG_RX_OK_PKT_CNTR);
982+ (void) cns21xx_gec_rr(gec, GEC_REG_RX_OK_BYTE_CNTR);
983+ (void) cns21xx_gec_rr(gec, GEC_REG_RX_RUNT_BYTE_CNTR);
984+ (void) cns21xx_gec_rr(gec, GEC_REG_RX_OSIZE_DROP_PKT_CNTR);
985+ (void) cns21xx_gec_rr(gec, GEC_REG_RX_NO_BUF_DROP_PKT_CNTR);
986+ (void) cns21xx_gec_rr(gec, GEC_REG_RX_CRC_ERR_PKT_CNTR);
987+ (void) cns21xx_gec_rr(gec, GEC_REG_RX_ARL_DROP_PKT_CNTR);
988+ (void) cns21xx_gec_rr(gec, GEC_REG_MYVLANID_MISMATCH_DROP_PKT_CNTR);
989+ (void) cns21xx_gec_rr(gec, GEC_REG_RX_CHKSUM_ERR_PKT_CNTR);
990+ (void) cns21xx_gec_rr(gec, GEC_REG_RX_PAUSE_FRAME_PKT_CNTR);
991+ (void) cns21xx_gec_rr(gec, GEC_REG_TX_OK_PKT_CNTR);
992+ (void) cns21xx_gec_rr(gec, GEC_REG_TX_OK_BYTE_CNTR);
993+ (void) cns21xx_gec_rr(gec, GEC_REG_TX_PAUSE_FRAME_CNTR);
994+ local_irq_restore(flags);
995+}
996+
997+static void cns21xx_gec_mib_read(struct cns21xx_gec *gec)
998+{
999+ unsigned long flags;
1000+
1001+ local_irq_save(flags);
1002+ gec->mib_info.mib_rx_ok_pkt +=
1003+ cns21xx_gec_rr(gec, GEC_REG_RX_OK_PKT_CNTR);
1004+ gec->mib_info.mib_rx_ok_byte +=
1005+ cns21xx_gec_rr(gec, GEC_REG_RX_OK_BYTE_CNTR);
1006+ gec->mib_info.mib_rx_runt +=
1007+ cns21xx_gec_rr(gec, GEC_REG_RX_RUNT_BYTE_CNTR);
1008+ gec->mib_info.mib_rx_over_size +=
1009+ cns21xx_gec_rr(gec, GEC_REG_RX_OSIZE_DROP_PKT_CNTR);
1010+ gec->mib_info.mib_rx_no_buffer_drop +=
1011+ cns21xx_gec_rr(gec, GEC_REG_RX_NO_BUF_DROP_PKT_CNTR);
1012+ gec->mib_info.mib_rx_crc_err +=
1013+ cns21xx_gec_rr(gec, GEC_REG_RX_CRC_ERR_PKT_CNTR);
1014+ gec->mib_info.mib_rx_arl_drop +=
1015+ cns21xx_gec_rr(gec, GEC_REG_RX_ARL_DROP_PKT_CNTR);
1016+ gec->mib_info.mib_rx_myvid_drop +=
1017+ cns21xx_gec_rr(gec, GEC_REG_MYVLANID_MISMATCH_DROP_PKT_CNTR);
1018+ gec->mib_info.mib_rx_csum_err +=
1019+ cns21xx_gec_rr(gec, GEC_REG_RX_CHKSUM_ERR_PKT_CNTR);
1020+ gec->mib_info.mib_rx_pause_frame +=
1021+ cns21xx_gec_rr(gec, GEC_REG_RX_PAUSE_FRAME_PKT_CNTR);
1022+ gec->mib_info.mib_tx_ok_pkt +=
1023+ cns21xx_gec_rr(gec, GEC_REG_TX_OK_PKT_CNTR);
1024+ gec->mib_info.mib_tx_ok_byte +=
1025+ cns21xx_gec_rr(gec, GEC_REG_TX_OK_BYTE_CNTR);
1026+ gec->mib_info.mib_tx_pause_frame +=
1027+ cns21xx_gec_rr(gec, GEC_REG_TX_PAUSE_FRAME_CNTR);
1028+ local_irq_restore(flags);
1029+}
1030+
1031+static const char *cns21xx_gec_speed_str(u32 phy_ctrl1)
1032+{
1033+ switch ((phy_ctrl1 >> 2) & 3) {
1034+ case 0:
1035+ return "10";
1036+ case 1:
1037+ return "100";
1038+ case 2:
1039+ return "1000";
1040+ }
1041+
1042+ return "???";
1043+}
1044+
1045+static irqreturn_t cns21xx_gec_status_isr(int irq, void *dev_id)
1046+{
1047+ struct cns21xx_gec *gec = dev_id;
1048+ u32 int_status;
1049+
1050+ int_status = cns21xx_gec_rr(gec, GEC_REG_INT);
1051+ cns21xx_gec_wr(gec, GEC_REG_INT, int_status);
1052+
1053+ /* flush write */
1054+ (void) cns21xx_gec_rr(gec, GEC_REG_INT);
1055+
1056+ if (int_status & GEC_INT_MIB_COUNTER_TH)
1057+ cns21xx_gec_mib_read(gec);
1058+
1059+ if (int_status & GEC_INT_PORT_STATUS_CHG) {
1060+ u32 phy_ctrl1;
1061+
1062+ phy_ctrl1 = cns21xx_gec_rr(gec, GEC_REG_PHY_CTRL1);
1063+ if (phy_ctrl1 & BIT(0)) {
1064+ netif_carrier_on(gec->netdev);
1065+ dev_info(&gec->netdev->dev,
1066+ "link up (%sMbps/%s duplex)\n",
1067+ cns21xx_gec_speed_str(phy_ctrl1),
1068+ (phy_ctrl1 & BIT(4)) ? "Full" : "Half");
1069+ } else {
1070+ netif_carrier_off(gec->netdev);
1071+ dev_info(&gec->netdev->dev, "link down\n");
1072+ }
1073+ }
1074+
1075+ return IRQ_HANDLED;
1076+}
1077+
1078+static inline void cns21xx_gec_enable_interrupt(struct cns21xx_gec *gec,
1079+ u32 mask)
1080+{
1081+ cns21xx_gec_wr(gec, GEC_REG_INT_MASK,
1082+ cns21xx_gec_rr(gec, GEC_REG_INT_MASK) & ~mask);
1083+}
1084+
1085+static int cns21xx_gec_install_status_isr(struct cns21xx_gec *gec)
1086+{
1087+ int err;
1088+
1089+ err = request_irq(gec->status_irq, cns21xx_gec_status_isr,
1090+ IRQF_DISABLED, dev_name(&gec->netdev->dev), gec);
1091+
1092+ if (err) {
1093+ dev_err(&gec->netdev->dev,
1094+ "unable to get IRQ %d (err=%d)\n",
1095+ gec->status_irq, err);
1096+ return err;
1097+ }
1098+
1099+ cns21xx_gec_enable_interrupt(gec, GEC_INT_MIB_COUNTER_TH |
1100+ GEC_INT_PORT_STATUS_CHG);
1101+
1102+ return 0;
1103+}
1104+
1105+static inline void cns21xx_gec_uninstall_status_isr(struct cns21xx_gec *gec)
1106+{
1107+ free_irq(gec->status_irq, gec);
1108+}
1109+
1110+static void cns21xx_gec_uninstall_isr(struct cns21xx_gec *gec)
1111+{
1112+ cns21xx_gec_uninstall_rxqf_isr(gec);
1113+ cns21xx_gec_uninstall_status_isr(gec);
1114+ cns21xx_gec_uninstall_receive_isr(gec);
1115+}
1116+
1117+static int cns21xx_gec_install_isr(struct cns21xx_gec *gec)
1118+{
1119+ int err;
1120+
1121+ /* setup delayed interrupts */
1122+ cns21xx_gec_wr(gec, GEC_REG_DLY_INT_CFG,
1123+ (1 << 16) |
1124+ ((CNS21XX_PEND_INT_COUNT & 0xFF) << 8) |
1125+ (CNS21XX_PEND_INT_TIME & 0xFF));
1126+
1127+ err = cns21xx_gec_install_receive_isr(gec);
1128+ if (err)
1129+ goto err_out;
1130+
1131+ err = cns21xx_gec_install_rxqf_isr(gec);
1132+ if (err)
1133+ goto err_uninstall_receive;
1134+
1135+ err = cns21xx_gec_install_status_isr(gec);
1136+ if (err)
1137+ goto err_uninstall_rxqf;
1138+
1139+ return 0;
1140+
1141+ err_uninstall_rxqf:
1142+ cns21xx_gec_uninstall_rxqf_isr(gec);
1143+ err_uninstall_receive:
1144+ cns21xx_gec_uninstall_receive_isr(gec);
1145+ err_out:
1146+ return err;
1147+}
1148+
1149+static int cns21xx_gec_lan_open(struct net_device *dev)
1150+{
1151+ struct cns21xx_gec *gec = netdev_priv(dev);
1152+ int err;
1153+
1154+ dev_dbg(&gec->netdev->dev, "open\n");
1155+
1156+#ifdef MODULE
1157+ MOD_INC_USE_COUNT;
1158+#endif
1159+
1160+ napi_enable(&gec->napi);
1161+ netif_start_queue(dev);
1162+ err = cns21xx_gec_install_isr(gec);
1163+ if (err)
1164+ goto err;
1165+
1166+ cns21xx_gec_enable(gec);
1167+
1168+ return 0;
1169+
1170+ err:
1171+ netif_stop_queue(dev);
1172+ napi_disable(&gec->napi);
1173+ return err;
1174+}
1175+
1176+static void cns21xx_gec_timeout(struct net_device *dev)
1177+{
1178+ dev_dbg(&dev->dev, "timeout\n");
1179+ netif_wake_queue(dev);
1180+ dev->trans_start = jiffies;
1181+}
1182+
1183+static int cns21xx_gec_close(struct net_device *dev)
1184+{
1185+ struct cns21xx_gec *gec = netdev_priv(dev);
1186+
1187+ cns21xx_gec_phy_powerdown(gec);
1188+ cns21xx_gec_uninstall_isr(gec);
1189+ napi_disable(&gec->napi);
1190+ netif_stop_queue(dev);
1191+ cns21xx_gec_shutdown(gec);
1192+
1193+#ifdef MODULE
1194+ MOD_DEC_USE_COUNT;
1195+#endif
1196+
1197+ return 0;
1198+}
1199+
1200+static inline struct sk_buff *cns21xx_gec_alloc_skb(void)
1201+{
1202+ struct sk_buff *skb;
1203+
1204+ skb = dev_alloc_skb(MAX_PACKET_LEN + 2);
1205+
1206+ if (unlikely(!skb))
1207+ return NULL;
1208+
1209+ /* Make buffer alignment 2 beyond a 16 byte boundary
1210+ * this will result in a 16 byte aligned IP header after
1211+ * the 14 byte MAC header is removed
1212+ */
1213+ skb_reserve(skb, 2); /* 16 bit alignment */
1214+
1215+ return skb;
1216+}
1217+
1218+static inline int cns21xx_gec_tx_dma_size(struct cns21xx_gec *gec)
1219+{
1220+ return gec->txring.count * sizeof(struct cns21xx_gec_txd);
1221+}
1222+
1223+static inline int cns21xx_gec_rx_dma_size(struct cns21xx_gec *gec)
1224+{
1225+ return gec->rxring.count * sizeof(struct cns21xx_gec_rxd);
1226+}
1227+
1228+static void __init cns21xx_gec_buffer_free(struct cns21xx_gec *gec)
1229+{
1230+ struct cns21xx_gec_ring *txring = &gec->txring;
1231+ struct cns21xx_gec_ring *rxring = &gec->rxring;
1232+ int i;
1233+
1234+ if (rxring->desc_cpu) {
1235+ for (i = 0; i < rxring->count; i++) {
1236+ if (rxring->skbs[i])
1237+ dev_kfree_skb(rxring->skbs[i]);
1238+ }
1239+
1240+ dma_free_coherent(gec->parent, cns21xx_gec_rx_dma_size(gec),
1241+ rxring->desc_cpu, rxring->desc_dma);
1242+ memset((void *)&rxring, 0, cns21xx_gec_rx_dma_size(gec));
1243+ }
1244+
1245+ if (txring->desc_cpu) {
1246+ dma_free_coherent(gec->parent, cns21xx_gec_tx_dma_size(gec),
1247+ txring->desc_cpu, txring->desc_dma);
1248+ memset((void *)&txring, 0, cns21xx_gec_tx_dma_size(gec));
1249+ }
1250+
1251+ kfree(txring->skbs);
1252+ kfree(rxring->skbs);
1253+}
1254+
1255+static int __init cns21xx_gec_buffer_alloc(struct cns21xx_gec *gec)
1256+{
1257+ struct cns21xx_gec_ring *txring = &gec->txring;
1258+ struct cns21xx_gec_ring *rxring = &gec->rxring;
1259+ struct cns21xx_gec_rxd *rxd;
1260+ struct cns21xx_gec_txd *txd;
1261+ struct sk_buff *skb;
1262+ int err = -ENOMEM;
1263+ int i;
1264+
1265+ rxring->skbs = kzalloc(rxring->count * sizeof(struct skb *),
1266+ GFP_KERNEL);
1267+
1268+ if (rxring->skbs == NULL) {
1269+ dev_err(&gec->netdev->dev,
1270+ "%s allocation failed\n", "RX buffer");
1271+ goto err_out;
1272+ }
1273+
1274+ txring->skbs = kzalloc(txring->count * sizeof(struct skb *),
1275+ GFP_KERNEL);
1276+
1277+ if (txring->skbs == NULL) {
1278+ dev_err(&gec->netdev->dev,
1279+ "%s allocation failed\n", "TX buffer");
1280+ goto err_out;
1281+ }
1282+
1283+ rxring->desc_cpu = dma_alloc_coherent(gec->parent,
1284+ cns21xx_gec_rx_dma_size(gec),
1285+ &rxring->desc_dma,
1286+ GFP_KERNEL);
1287+ if (!rxring->desc_cpu) {
1288+ dev_err(&gec->netdev->dev,
1289+ "%s allocation failed\n", "RX ring");
1290+ goto err_out;
1291+ }
1292+
1293+ txring->desc_cpu = dma_alloc_coherent(gec->parent,
1294+ cns21xx_gec_tx_dma_size(gec),
1295+ &txring->desc_dma,
1296+ GFP_KERNEL);
1297+ if (!txring->desc_cpu) {
1298+ dev_err(&gec->netdev->dev,
1299+ "%s allocation failed\n", "TX ring");
1300+ goto err_out;
1301+ }
1302+
1303+ /* Clean RX Memory */
1304+ memset((void *)rxring->desc_cpu, 0, cns21xx_gec_rx_dma_size(gec));
1305+ dev_dbg(&gec->netdev->dev,
1306+ "rxring->desc_cpu=0x%08X rxring->desc_dma=0x%08X\n",
1307+ (u32) rxring->desc_cpu,
1308+ (u32) rxring->desc_dma);
1309+
1310+ /* Set cur_index Point to Zero */
1311+ rxring->curr = 0;
1312+ rxd = rxring->desc_cpu;
1313+ for (i = 0; i < rxring->count; i++, rxd++) {
1314+ if (i == (rxring->count - 1)) {
1315+ /* End bit == 0; */
1316+ rxd->eor = 1;
1317+ }
1318+ skb = cns21xx_gec_alloc_skb();
1319+ if (!skb) {
1320+ dev_err(&gec->netdev->dev,
1321+ "%s allocation failed\n", "skb");
1322+ goto err_out;
1323+ }
1324+
1325+ /* Trans Packet from Virtual Memory to Physical Memory */
1326+ rxring->skbs[i] = skb;
1327+ rxd->sdp = dma_map_single(gec->parent,
1328+ skb->data,
1329+ MAX_PACKET_LEN,
1330+ DMA_TO_DEVICE);
1331+ rxd->length = MAX_PACKET_LEN;
1332+ }
1333+
1334+ /* Clear TX Memory */
1335+ memset((void *)txring->desc_cpu, 0, cns21xx_gec_tx_dma_size(gec));
1336+ dev_dbg(&gec->netdev->dev,
1337+ "txring->desc_cpu=0x%08X txring->desc_dma=0x%08X\n",
1338+ (u32) txring->desc_cpu,
1339+ (u32) txring->desc_dma);
1340+
1341+ /* Set cur_index Point to Zero */
1342+ txring->curr = 0;
1343+ txd = txring->desc_cpu;
1344+ for (i = 0; i < txring->count; i++, txd++) {
1345+ if (i == (txring->count - 1)) {
1346+ /* End of Ring ==1 */
1347+ txd->eor = 1;
1348+ }
1349+ /* TX Ring , Cown == 1 */
1350+ txd->cown = 1;
1351+
1352+#ifdef CNS21XX_GEC_TX_HW_CHECKSUM
1353+ /* Enable Checksum */
1354+ txd->ico = 1;
1355+ txd->uco = 1;
1356+ txd->tco = 1;
1357+#else
1358+ txd->ico = 0;
1359+ txd->uco = 0;
1360+ txd->tco = 0;
1361+#endif
1362+ /* clear txring->skbs */
1363+ txring->skbs[i] = NULL;
1364+ }
1365+
1366+ return 0;
1367+
1368+err_out:
1369+ cns21xx_gec_buffer_free(gec);
1370+ return err;
1371+}
1372+
1373+static int cns21xx_gec_get_rfd_buff(struct cns21xx_gec *gec, int index)
1374+{
1375+ struct cns21xx_gec_ring *rxring = &gec->rxring;
1376+ struct cns21xx_gec_rxd *rxd;
1377+ struct sk_buff *skb;
1378+ unsigned char *data;
1379+ int len;
1380+
1381+ /* TODO: get rxdesc ptr */
1382+ rxd = ((struct cns21xx_gec_rxd *) rxring->desc_cpu) + index;
1383+ skb = rxring->skbs[index];
1384+
1385+ len = rxd->length;
1386+
1387+ dma_unmap_single(gec->parent, rxd->sdp, len,
1388+ DMA_FROM_DEVICE);
1389+
1390+ data = skb_put(skb, len);
1391+
1392+ skb->dev = gec->netdev;
1393+
1394+#ifdef CNS21XX_GEC_RX_HW_CHECKSUM
1395+ if (rxd->ipf == 1 || rxd->l4f == 1) {
1396+ if (rxd->prot != 0x11) {
1397+ skb->ip_summed = CHECKSUM_NONE;
1398+ } else {
1399+ /* CheckSum Fail */
1400+ skb->dev->stats.rx_errors++;
1401+ goto freepacket;
1402+ }
1403+ } else {
1404+ skb->ip_summed = CHECKSUM_UNNECESSARY;
1405+ }
1406+#else
1407+ skb->ip_summed = CHECKSUM_NONE;
1408+#endif
1409+
1410+ /* this line must, if no, packet will not send to network layer */
1411+ skb->protocol = eth_type_trans(skb, skb->dev);
1412+
1413+ skb->dev->stats.rx_packets++;
1414+ skb->dev->stats.rx_bytes += len;
1415+ skb->dev->last_rx = jiffies;
1416+
1417+ /* if netif_rx any package, will let this driver core dump. */
1418+ netif_receive_skb(skb);
1419+
1420+ return 0;
1421+
1422+freepacket:
1423+ dev_kfree_skb_any(skb);
1424+ return 0;
1425+}
1426+
1427+static void cns21xx_gec_receive_packet(struct cns21xx_gec *gec,
1428+ int mode, int *work_done, int work_to_do)
1429+{
1430+ struct cns21xx_gec_ring *rxring = &gec->rxring;
1431+ int rxsd_index;
1432+ u32 rxsd_current;
1433+ struct cns21xx_gec_rxd *rxd;
1434+ struct sk_buff *skb;
1435+ int i, rxcount = 0;
1436+
1437+ rxd = ((struct cns21xx_gec_rxd *) rxring->desc_cpu) + rxring->curr;
1438+ rxsd_current = cns21xx_gec_rr(gec, GEC_REG_RX_DPTR);
1439+ rxsd_index = (rxsd_current - (u32)rxring->desc_dma) >> 4;
1440+
1441+ if (rxsd_index > rxring->curr) {
1442+ rxcount = rxsd_index - rxring->curr;
1443+ } else if (rxsd_index < rxring->curr) {
1444+ rxcount = (rxring->count - rxring->curr) +
1445+ rxsd_index;
1446+ } else {
1447+ if (rxd->cown == 0) {
1448+ goto receive_packet_exit;
1449+ } else {
1450+ /* Queue Full */
1451+ rxcount = rxring->count;
1452+ }
1453+ }
1454+
1455+ for (i = 0; i < rxcount; i++) {
1456+ if (*work_done >= work_to_do)
1457+ break;
1458+
1459+ ++(*work_done);
1460+
1461+ if (rxd->cown != 0) {
1462+ /* Alloc New skb_buff */
1463+ skb = cns21xx_gec_alloc_skb();
1464+
1465+ /* Check skb_buff */
1466+ if (skb != NULL) {
1467+ cns21xx_gec_get_rfd_buff(gec, rxring->curr);
1468+ rxring->skbs[rxring->curr] = skb;
1469+ rxd->sdp =
1470+ dma_map_single(gec->parent,
1471+ skb->data,
1472+ MAX_PACKET_LEN,
1473+ DMA_TO_DEVICE);
1474+ rxd->length = MAX_PACKET_LEN;
1475+
1476+ /* set cbit to 0 for CPU Transfer */
1477+ rxd->cown = 0;
1478+ } else {
1479+ /*
1480+ * TODO: I will add dev->lp.stats->rx_dropped,
1481+ * it will effect the performance
1482+ */
1483+ dev_warn(&gec->netdev->dev,
1484+ "skb allocation failed, reuse the buffer\n");
1485+
1486+ /* set cbit to 0 for CPU Transfer */
1487+ rxd->cown = 0;
1488+ return;
1489+ }
1490+ } else {
1491+#if 0
1492+ dev_err(&gec->netdev->dev, "encounter COWN == 0 BUG\n");
1493+#endif
1494+ }
1495+
1496+ if (rxring->curr == (rxring->count - 1)) {
1497+ rxring->curr = 0;
1498+ rxd = rxring->desc_cpu;
1499+ } else {
1500+ rxring->curr++;
1501+ rxd++;
1502+ }
1503+ }
1504+
1505+ receive_packet_exit:
1506+ return;
1507+}
1508+
1509+static int cns21xx_gec_poll(struct napi_struct *napi, int budget)
1510+{
1511+ struct cns21xx_gec *gec;
1512+ int work_done = 0;
1513+ int work_to_do = budget;
1514+
1515+ gec = container_of(napi, struct cns21xx_gec, napi);
1516+ cns21xx_gec_receive_packet(gec, 0, &work_done, work_to_do);
1517+
1518+ budget -= work_done;
1519+
1520+ /* if no Tx and not enough Rx work done, exit the polling mode */
1521+ if (work_done) {
1522+ if (test_bit(0, &gec->rx_queue_full) == 1) {
1523+ /* queue full */
1524+ clear_bit(0, &gec->rx_queue_full);
1525+ /* start Rx DMA */
1526+ cns21xx_gec_wr(gec, GEC_REG_RX_DMA_CTRL, 1);
1527+ return 1;
1528+ }
1529+ } else {
1530+ napi_complete(&gec->napi);
1531+#ifdef CONFIG_STAR_NIC_NAPI_MASK_IRQ
1532+ enable_irq(gec->rxrc_irq);
1533+#endif
1534+ return 0;
1535+ }
1536+
1537+ return work_done;
1538+}
1539+
1540+static int cns21xx_gec_send_packet(struct sk_buff *skb, struct net_device *dev)
1541+{
1542+ struct cns21xx_gec *gec = netdev_priv(dev);
1543+ struct cns21xx_gec_txd *txd;
1544+ struct cns21xx_gec_ring *txring = &gec->txring;
1545+ struct sk_buff *skb_free = NULL;
1546+ unsigned long flags;
1547+ unsigned int len;
1548+
1549+ if (skb_padto(skb, ETH_ZLEN))
1550+ return NETDEV_TX_OK;
1551+
1552+ len = max_t(unsigned int, skb->len, ETH_ZLEN);
1553+
1554+ spin_lock_irqsave(&gec->tx_lock, flags);
1555+
1556+ txd = ((struct cns21xx_gec_txd *) txring->desc_cpu) + txring->curr;
1557+ if (txd->cown == 0) {
1558+ /* This TFD is busy */
1559+ spin_unlock_irqrestore(&gec->tx_lock, flags);
1560+ /* re-queue the skb */
1561+ return NETDEV_TX_BUSY;
1562+ }
1563+
1564+ if (txd->sdp != 0) {
1565+ /* MUST TODO: Free skbuff */
1566+ skb_free = txring->skbs[txring->curr];
1567+
1568+ dma_unmap_single(gec->parent,
1569+ txd->sdp,
1570+ txd->length,
1571+ DMA_TO_DEVICE);
1572+ txring->dirty = txring->curr + 1;
1573+ if (txring->dirty == txring->count)
1574+ txring->dirty = 0;
1575+ }
1576+
1577+#ifdef CNS21XX_GEC_TX_HW_CHECKSUM
1578+ if (skb->protocol == __constant_htons(ETH_P_IP)) {
1579+ if (ip_hdr(skb)->protocol == IPPROTO_UDP) {
1580+ txd->uco = 1;
1581+ txd->tco = 0;
1582+ } else if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
1583+ txd->uco = 0;
1584+ txd->tco = 1;
1585+ } else {
1586+ txd->uco = 0;
1587+ txd->tco = 0;
1588+ }
1589+ } else {
1590+ txd->ico = 0;
1591+ txd->uco = 0;
1592+ txd->tco = 0;
1593+ }
1594+#endif /* CNS21XX_GEC_TX_HW_CHECKSUM */
1595+
1596+ txring->skbs[txring->curr] = skb;
1597+
1598+ txd->length = len;
1599+ txd->sdp = dma_map_single(gec->parent, skb->data, len,
1600+ DMA_TO_DEVICE);
1601+
1602+ txd->fs = 1;
1603+ txd->ls = 1;
1604+
1605+ /* Wake interrupt */
1606+ txd->intr = 0;
1607+ txd->cown = 0;
1608+
1609+ mb();
1610+
1611+ /* Start Tx DMA */
1612+ cns21xx_gec_wr(gec, GEC_REG_TX_DMA_CTRL, 1);
1613+
1614+ dev->stats.tx_packets++;
1615+ dev->stats.tx_bytes += skb->len;
1616+ dev->trans_start = jiffies;
1617+
1618+ txring->curr++;
1619+ if (txring->curr == txring->count)
1620+ txring->curr = 0;
1621+
1622+ spin_unlock_irqrestore(&gec->tx_lock, flags);
1623+
1624+ if (skb_free)
1625+ dev_kfree_skb(skb_free);
1626+
1627+ cns21xx_gec_timer_modify(gec, 10);
1628+
1629+ return NETDEV_TX_OK;
1630+}
1631+
1632+static void cns21xx_gec_set_mac_addr(struct cns21xx_gec *gec,
1633+ const char *mac_addr)
1634+{
1635+ cns21xx_gec_wr(gec, GEC_REG_MY_MAC_H,
1636+ (mac_addr[0] << 8) | mac_addr[1]);
1637+
1638+ cns21xx_gec_wr(gec, GEC_REG_MY_MAC_L,
1639+ (mac_addr[2] << 24) | (mac_addr[3] << 16) |
1640+ (mac_addr[4] << 8) | mac_addr[5]);
1641+
1642+ dev_dbg(&gec->netdev->dev, "MAC address: %pM", mac_addr);
1643+}
1644+
1645+static int cns21xx_gec_set_lan_mac_addr(struct net_device *dev, void *addr)
1646+{
1647+ struct sockaddr *sock_addr = addr;
1648+ struct cns21xx_gec *gec = netdev_priv(dev);
1649+
1650+ spin_lock_irq(&gec->lock);
1651+ memcpy(dev->dev_addr, sock_addr->sa_data, 6);
1652+ cns21xx_gec_set_mac_addr(gec, sock_addr->sa_data);
1653+ spin_unlock_irq(&gec->lock);
1654+
1655+ return 0;
1656+}
1657+
1658+static int __init cns21xx_gec_setup(struct cns21xx_gec *gec)
1659+{
1660+ int err;
1661+
1662+ /* set high */
1663+ PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
1664+ /* set low */
1665+ PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << 15);
1666+ /* set high */
1667+ PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
1668+ /* set NIC clock to 67.5MHz */
1669+ PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 7);
1670+
1671+ /* enable NIC clock */
1672+ HAL_PWRMGT_ENABLE_NIC_CLOCK();
1673+#if 0
1674+ cns21xx_gec_wr(gec, GEC_REG_MAC_CFG, 0x00527C00);
1675+#endif
1676+ udelay(100);
1677+
1678+ /* Configure GPIO for NIC MDC/MDIO pins */
1679+ HAL_MISC_ENABLE_MDC_MDIO_PINS();
1680+ HAL_MISC_ENABLE_NIC_COL_PINS();
1681+
1682+#if 0
1683+ MISC_GPIOA_PIN_ENABLE_REG |= (0x7 << 22);
1684+ MISC_FAST_ETHERNET_PHY_CONFIG_REG |= (FE_PHY_LED_MODE >> 12) & 0x3;
1685+
1686+ /* set high */
1687+ PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
1688+ /* set low */
1689+ PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << 15);
1690+ /* set high */
1691+ PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
1692+#endif
1693+
1694+ /* disable all interrupt status sources */
1695+ cns21xx_gec_wr(gec, GEC_REG_INT_MASK, ~(0));
1696+ /* clear pending interrupts */
1697+ cns21xx_gec_wr(gec, GEC_REG_INT, ~(0));
1698+
1699+ /* stop Rx and Tx DMA */
1700+ cns21xx_gec_wr(gec, GEC_REG_TX_DMA_CTRL, 0);
1701+ cns21xx_gec_wr(gec, GEC_REG_RX_DMA_CTRL, 0);
1702+
1703+ gec->txring.count = CNS21XX_GEC_NUM_TXDS;
1704+ gec->rxring.count = CNS21XX_GEC_NUM_RXDS;
1705+ err = cns21xx_gec_buffer_alloc(gec);
1706+ if (err)
1707+ return err;
1708+
1709+ cns21xx_gec_mac_config(gec);
1710+ cns21xx_gec_fc_config(gec);
1711+
1712+ err = cns21xx_gec_phy_config(gec);
1713+ if (err) {
1714+ cns21xx_gec_buffer_free(gec);
1715+ return err;
1716+ }
1717+
1718+ cns21xx_gec_vlan_config(gec);
1719+ cns21xx_gec_arl_config(gec);
1720+ cns21xx_gec_set_mac_addr(gec, gec->netdev->dev_addr);
1721+ cns21xx_gec_mib_reset(gec);
1722+
1723+ MISC_DEBUG_PROBE_SELECTION_REG = 0x00000125; /* 0x00000105 pb0_nic */
1724+
1725+ cns21xx_gec_wr(gec, GEC_REG_TX_DPTR, gec->txring.desc_dma);
1726+ cns21xx_gec_wr(gec, GEC_REG_TX_BASE_ADDR, gec->txring.desc_dma);
1727+ cns21xx_gec_wr(gec, GEC_REG_RX_DPTR, gec->rxring.desc_dma);
1728+ cns21xx_gec_wr(gec, GEC_REG_RX_BASE_ADDR, gec->rxring.desc_dma);
1729+
1730+ cns21xx_gec_dma_config(gec);
1731+ internal_phy_init_timer(gec);
1732+ cns21xx_gec_timer_init(gec);
1733+
1734+ return 0;
1735+}
1736+
1737+static const struct net_device_ops cns21xx_gec_netdev_ops = {
1738+ .ndo_open = cns21xx_gec_lan_open,
1739+ .ndo_stop = cns21xx_gec_close,
1740+ .ndo_start_xmit = cns21xx_gec_send_packet,
1741+ .ndo_set_mac_address = cns21xx_gec_set_lan_mac_addr,
1742+ .ndo_tx_timeout = cns21xx_gec_timeout,
1743+ .ndo_validate_addr = eth_validate_addr,
1744+ .ndo_change_mtu = eth_change_mtu,
1745+};
1746+
1747+static int __init cns21xx_gec_probe(struct platform_device *pdev)
1748+{
1749+ struct net_device *netdev;
1750+ struct cns21xx_gec *gec;
1751+ struct cns21xx_gec_plat_data *pdata;
1752+ int err;
1753+
1754+ pdata = pdev->dev.platform_data;
1755+ if (!pdata) {
1756+ dev_dbg(&pdev->dev, "no platform data\n");
1757+ err = -EINVAL;
1758+ goto err_out;
1759+ }
1760+
1761+ if (!pdata->mac_addr) {
1762+ dev_dbg(&pdev->dev, "no mac address\n");
1763+ err = -EINVAL;
1764+ goto err_out;
1765+ }
1766+
1767+ netdev = alloc_etherdev(sizeof(struct cns21xx_gec));
1768+ if (!netdev) {
1769+ err = -ENOMEM;
1770+ goto err_out;
1771+ }
1772+
1773+ SET_NETDEV_DEV(netdev, &pdev->dev);
1774+
1775+ gec = netdev_priv(netdev);
1776+ gec->pdata = pdata;
1777+ gec->parent = &pdev->dev;
1778+
1779+ gec->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1780+ if (!gec->mem_res) {
1781+ dev_dbg(&pdev->dev, "no iomem resource\n");
1782+ err = -EINVAL;
1783+ goto err_free_netdev;
1784+ }
1785+
1786+ gec->status_irq = platform_get_irq_byname(pdev,
1787+ CNS21XX_GEC_STATUS_IRQ_NAME);
1788+ if (gec->status_irq < 0) {
1789+ dev_dbg(&pdev->dev, "%s irq not specified\n",
1790+ CNS21XX_GEC_STATUS_IRQ_NAME);
1791+ err = -EINVAL;
1792+ goto err_free_netdev;
1793+ }
1794+
1795+ gec->rxrc_irq = platform_get_irq_byname(pdev,
1796+ CNS21XX_GEC_RXRC_IRQ_NAME);
1797+ if (gec->rxrc_irq < 0) {
1798+ dev_dbg(&pdev->dev, "%s irq not specified\n",
1799+ CNS21XX_GEC_RXRC_IRQ_NAME);
1800+ err = -EINVAL;
1801+ goto err_free_netdev;
1802+ }
1803+
1804+ gec->rxqf_irq = platform_get_irq_byname(pdev,
1805+ CNS21XX_GEC_RXQF_IRQ_NAME);
1806+ if (gec->rxqf_irq < 0) {
1807+ dev_dbg(&pdev->dev, "%s irq not specified\n",
1808+ CNS21XX_GEC_RXQF_IRQ_NAME);
1809+ err = -EINVAL;
1810+ goto err_free_netdev;
1811+ }
1812+
1813+ gec->txtc_irq = platform_get_irq_byname(pdev,
1814+ CNS21XX_GEC_TXTC_IRQ_NAME);
1815+ if (gec->txtc_irq < 0) {
1816+ dev_dbg(&pdev->dev, "%s irq not specified\n",
1817+ CNS21XX_GEC_TXTC_IRQ_NAME);
1818+ err = -EINVAL;
1819+ goto err_free_netdev;
1820+ }
1821+
1822+ gec->txqe_irq = platform_get_irq_byname(pdev,
1823+ CNS21XX_GEC_TXQE_IRQ_NAME);
1824+ if (gec->txqe_irq < 0) {
1825+ dev_dbg(&pdev->dev, "%s irq not specified\n",
1826+ CNS21XX_GEC_TXQE_IRQ_NAME);
1827+ err = -EINVAL;
1828+ goto err_free_netdev;
1829+ }
1830+
1831+ if (!request_mem_region(gec->mem_res->start,
1832+ resource_size(gec->mem_res), pdev->name)) {
1833+ dev_err(&pdev->dev, "unable to request mem region\n");
1834+ err = -EBUSY;
1835+ goto err_free_netdev;
1836+ }
1837+
1838+ gec->base = ioremap(gec->mem_res->start, resource_size(gec->mem_res));
1839+ if (!gec->base) {
1840+ dev_err(&pdev->dev, "ioremap failed \n");
1841+ err = -ENXIO;
1842+ goto err_release_mem;
1843+ }
1844+
1845+ platform_set_drvdata(pdev, netdev);
1846+
1847+ spin_lock_init(&gec->lock);
1848+ spin_lock_init(&gec->tx_lock);
1849+
1850+ netdev->base_addr = gec->mem_res->start;
1851+ netdev->netdev_ops = &cns21xx_gec_netdev_ops;
1852+#if defined(CNS21XX_GEC_TX_HW_CHECKSUM)
1853+ netdev->features = NETIF_F_IP_CSUM;
1854+#endif
1855+ memcpy(netdev->dev_addr, pdata->mac_addr, 6);
1856+ netif_napi_add(netdev, &gec->napi, cns21xx_gec_poll, 64);
1857+
1858+ gec->netdev = netdev;
1859+ err = register_netdev(netdev);
1860+ if (err)
1861+ goto err_unmap;
1862+
1863+ err = cns21xx_gec_setup(gec);
1864+ if (err)
1865+ goto err_unregister_netdev;
1866+
1867+ return 0;
1868+
1869+ err_unregister_netdev:
1870+ unregister_netdev(netdev);
1871+ err_unmap:
1872+ platform_set_drvdata(pdev, NULL);
1873+ iounmap(gec->base);
1874+ err_release_mem:
1875+ release_mem_region(gec->mem_res->start, resource_size(gec->mem_res));
1876+ err_free_netdev:
1877+ free_netdev(netdev);
1878+ err_out:
1879+ return err;
1880+}
1881+
1882+static int __devexit cns21xx_gec_remove(struct platform_device *pdev)
1883+{
1884+ struct net_device *netdev = platform_get_drvdata(pdev);
1885+ struct cns21xx_gec *gec = netdev_priv(netdev);
1886+
1887+ unregister_netdev(netdev);
1888+ platform_set_drvdata(pdev, NULL);
1889+ iounmap(gec->base);
1890+ release_mem_region(gec->mem_res->start, resource_size(gec->mem_res));
1891+ free_netdev(netdev);
1892+
1893+ return 0;
1894+}
1895+
1896+static struct platform_driver cns21xx_gec_driver = {
1897+ .remove = __devexit_p(cns21xx_gec_remove),
1898+ .driver = {
1899+ .name = "cns21xx-gec",
1900+ .owner = THIS_MODULE,
1901+ }
1902+};
1903+
1904+static int __init cns21xx_gec_init(void)
1905+{
1906+ return platform_driver_probe(&cns21xx_gec_driver, cns21xx_gec_probe);
1907+}
1908+
1909+static void __exit cns21xx_gec_exit(void)
1910+{
1911+ platform_driver_unregister(&cns21xx_gec_driver);
1912+}
1913+
1914+module_init(cns21xx_gec_init);
1915+module_exit(cns21xx_gec_exit);
1916+
1917+#define INTERNAL_PHY_PATCH_CHECKCNT 16
1918+#define INTERNAL_PHY_PATCH_CHECK_PERIOD 1000 /* ms */
1919+
1920+static void (*phy_statemachine)(struct cns21xx_gec*, int, int, int);
1921+
1922+#define ETH3220_PHY_MON_PERIOD INTERNAL_PHY_PATCH_CHECK_PERIOD
1923+
1924+/* phy monitor state */
1925+#define NUM_PHY 1
1926+#define PHY_STATE_INIT 0
1927+#define LINK_DOWN_POSITIVE 1
1928+#define WAIT_LINK_UP_POSITIVE 2
1929+#define LINK_UP_POSITIVE 3
1930+#define WAIT_BYPASS_LINK_UP_POSITIVE 4
1931+#define BYPASS_AND_LINK_UP_POSITIVE 5
1932+#define LINK_UP_8101_POSITIVE 6
1933+#define WAIT_8101_LINK_UP_POSITIVE 7
1934+
1935+#define PHY_STATE_LAST (WAIT_8101_LINK_UP_POSITIVE+1)
1936+
1937+/* time setting */
1938+#define WAIT_BYPASS_LINK_UP_POSITIVE_TIMEOUT 5000 /* 5000 ms */
1939+#define WAIT_BYPASS_LINK_UP_NEGATIVE_TIMEOUT 5000 /* 5000 ms */
1940+#define LINK_DOWN_ABILITY_DETECT_TIMEOUT 5000 /* 5000 ms */
1941+#define DETECT_8101_PERIOD 7000 /* 7000 ms */
1942+#define WAIT_8101_LINK_UP_TIMEOUT 3000 /* 3000 ms */
1943+
1944+#define MAX_PHY_PORT 1
1945+#define DEFAULT_AGC_TRAIN 16
1946+#define MAX_AGC_TRAIN 16 /* train 16 times */
1947+static int agc_train_num = DEFAULT_AGC_TRAIN;
1948+u32 port_displaybuf[NUM_PHY][MAX_AGC_TRAIN + 1] = {
1949+ {0}
1950+};
1951+
1952+static int cuv[3][3] = {
1953+ {1, 1, 4},
1954+ {1, 1, 0},
1955+ {1, 1, -4}
1956+};
1957+
1958+static u32 link_status_old;
1959+
1960+struct eth3220_phy {
1961+ u16 state;
1962+ u16 linkdown_cnt;
1963+ u32 state_time;
1964+ u32 timer;
1965+};
1966+
1967+#define DEBUG_PHY_STATE_TRANSITION 1
1968+#if DEBUG_PHY_STATE_TRANSITION
1969+/*
1970+ * show state transition of debug phy port.
1971+ * -1 for all ports
1972+ * -2 for disable all ports
1973+ * 0 - 4 for each port
1974+ */
1975+static int debug_phy_port = -2;
1976+static char *phystate_name[] = {
1977+ "init", /* PHY_STATE_INIT */
1978+ "ldp", /* LINK_DOWN_POSITIVE */
1979+ "wait_lup", /* WAIT_LINK_UP_POSITIVE */
1980+ "lup", /* LINK_UP_POSITIVE */
1981+ "wait_bp_lup", /* WAIT_BYPASS_LINK_UP_POSITIVE */
1982+ "bp_lup", /* BYPASS_AND_LINK_UP_POSITIVE */
1983+ "8101_lup", /* LINK_UP_8101_POSITIVE */
1984+ "wait_8101_lup", /* WAIT_8101_LINK_UP_POSITIVE */
1985+ "err",
1986+};
1987+#endif /* DEBUG_PHY_STATE_TRANSITION */
1988+
1989+static struct eth3220_phy phy[5] = {
1990+ {PHY_STATE_INIT, 0, 0, 0},
1991+ {PHY_STATE_INIT, 0, 0, 0},
1992+ {PHY_STATE_INIT, 0, 0, 0},
1993+ {PHY_STATE_INIT, 0, 0, 0},
1994+ {PHY_STATE_INIT, 0, 0, 0}
1995+};
1996+
1997+static u16 long_cable_global_reg[32] = {
1998+ 0x0000, 0x19a0, 0x1d00, 0x0e80,
1999+ 0x0f60, 0x07c0, 0x07e0, 0x03e0,
2000+ 0x0000, 0x0000, 0x0000, 0x2000,
2001+ 0x8250, 0x1700, 0x0000, 0x0000,
2002+ 0x0000, 0x0000, 0x0000, 0x0000,
2003+ 0x0000, 0x204b, 0x01c2, 0x0000,
2004+ 0x0000, 0x0000, 0x0fff, 0x4100,
2005+ 0x9319, 0x0021, 0x0034, 0x270a | FE_PHY_LED_MODE
2006+};
2007+
2008+static u16 long_cable_local_reg[32] = {
2009+ 0x3100, 0x786d, 0x01c1, 0xca51,
2010+ 0x05e1, 0x45e1, 0x0003, 0x001c,
2011+ 0x2000, 0x9828, 0xf3c4, 0x400c,
2012+ 0xf8ff, 0x6940, 0xb906, 0x503c,
2013+ 0x8000, 0x297a, 0x1010, 0x5010,
2014+ 0x6ae1, 0x7c73, 0x783c, 0xfbdf,
2015+ 0x2080, 0x3244, 0x1301, 0x1a80,
2016+ 0x8e8f, 0x8000, 0x9c29, 0xa70a | FE_PHY_LED_MODE
2017+};
2018+
2019+/*=============================================================*
2020+ * eth3220ac_rt8101_phy_setting
2021+ *=============================================================*/
2022+static void eth3220ac_rt8101_phy_setting(struct cns21xx_gec *gec, int port)
2023+{
2024+ cns21xx_gec_write_phy(gec, port, 12, 0x18ff);
2025+ cns21xx_gec_write_phy(gec, port, 18, 0x6400);
2026+}
2027+
2028+static void eth3220ac_release_bpf(struct cns21xx_gec *gec, int port)
2029+{
2030+ cns21xx_gec_write_phy(gec, port, 18, 0x6210);
2031+}
2032+
2033+static void eth3220ac_def_bpf(struct cns21xx_gec *gec, int port)
2034+{
2035+ cns21xx_gec_write_phy(gec, port, 18, 0x6bff);
2036+}
2037+
2038+static void eth3220ac_def_linkdown_setting(struct cns21xx_gec *gec, int port)
2039+{
2040+ cns21xx_gec_write_phy(gec, port, 13, 0xe901);
2041+ cns21xx_gec_write_phy(gec, port, 14, 0xa3c6);
2042+}
2043+
2044+static void eth3220ac_def_linkup_setting(struct cns21xx_gec *gec, int port)
2045+{
2046+ cns21xx_gec_write_phy(gec, port, 13, 0x6901);
2047+ cns21xx_gec_write_phy(gec, port, 14, 0xa286);
2048+}
2049+
2050+/*=============================================================*
2051+ * eth3220ac_link_agc:
2052+ *=============================================================*/
2053+static int eth3220ac_link_agc(struct cns21xx_gec *gec, int port, int speed)
2054+{
2055+ u16 reg;
2056+ u32 agc_data = 0;
2057+ u32 short_cable;
2058+ int i, jj;
2059+
2060+ /* if speed = 100MHz, then continue */
2061+ if (speed == 0)
2062+ return 0;
2063+
2064+ short_cable = 0;
2065+ jj = 0;
2066+ for (i = 0; i < agc_train_num; i++) {
2067+ cns21xx_gec_read_phy(gec, port, 15, &reg);
2068+ reg &= 0x7f;
2069+ if (reg <= 0x12) {
2070+ short_cable = 1;
2071+ jj++;
2072+ agc_data += (u32)reg;
2073+ }
2074+ }
2075+
2076+ if (short_cable)
2077+ agc_data = (agc_data / jj) + 4;
2078+ else
2079+ agc_data = (cuv[2][0] * agc_data) / cuv[2][1] /
2080+ agc_train_num - 4;
2081+
2082+ /* Fix AGC */
2083+ agc_data = 0xd0 | (agc_data << 9);
2084+ cns21xx_gec_write_phy(gec, port, 15, agc_data);
2085+ udelay(1000);
2086+ cns21xx_gec_read_phy(gec, port, 15, &reg);
2087+ reg &= ~(0x1 << 7);
2088+ cns21xx_gec_write_phy(gec, port, 15, reg);
2089+
2090+ return 0;
2091+}
2092+
2093+/*=============================================================*
2094+ * eth3220ac_unlink_agc:
2095+ *=============================================================*/
2096+static void eth3220ac_unlink_agc(struct cns21xx_gec *gec, int port)
2097+{
2098+ /* start AGC adaptive */
2099+ cns21xx_gec_write_phy(gec, port, 15, 0xa050);
2100+}
2101+
2102+/*=============================================================*
2103+ * eth3220ac_rt8100_check
2104+ *=============================================================*/
2105+static int eth3220ac_rt8100_check(struct cns21xx_gec *gec, int port)
2106+{
2107+ u16 reg, reg2;
2108+
2109+ /* Read reg27 (error register) */
2110+ cns21xx_gec_read_phy(gec, port, 27, &reg);
2111+ /* if error exists, set Bypass Filter enable */
2112+ if ((reg & 0xfffc)) {
2113+ cns21xx_gec_read_phy(gec, port, 15, &reg);
2114+ cns21xx_gec_read_phy(gec, port, 27, &reg2);
2115+ if ((reg2 & 0xfffc) && (((reg >> 9) & 0xff) < 0x1c)) {
2116+ dev_err(&gec->netdev->dev, "8100 pos err\n");
2117+
2118+ /* Bypass agcgain disable */
2119+ cns21xx_gec_write_phy(gec, port, 15, (reg & (~(0x1 << 7))));
2120+
2121+ /* repeat counts when reaching threshold error */
2122+ cns21xx_gec_write_phy(gec, port, 13, 0x4940);
2123+
2124+ /*
2125+ * Speed up AN speed and compensate threshold
2126+ * phase error
2127+ */
2128+ cns21xx_gec_write_phy(gec, port, 14, 0xa306);
2129+
2130+ /* Bypass Filter enable */
2131+ cns21xx_gec_read_phy(gec, port, 18, &reg2);
2132+
2133+ cns21xx_gec_write_phy(gec, port, 18, (reg | 0x400));
2134+
2135+ /* restart AN */
2136+ cns21xx_gec_write_phy(gec, port, 0, 0x3300);
2137+ return 1;
2138+ }
2139+ }
2140+ return 0;
2141+}
2142+
2143+
2144+/*=============================================================*
2145+ * eth3220ac_rt8100_linkdown
2146+ *=============================================================*/
2147+static void eth3220ac_rt8100_linkdown(struct cns21xx_gec *gec, int port)
2148+{
2149+ u16 reg;
2150+
2151+ /* Bypass Filter disable */
2152+ cns21xx_gec_read_phy(gec, port, 18, &reg);
2153+ cns21xx_gec_write_phy(gec, port, 18, (reg & (~(0x1 << 10))));
2154+ eth3220ac_def_linkdown_setting(gec, port);
2155+}
2156+
2157+static void eth3220ac_normal_phy_setting(struct cns21xx_gec *gec, int port)
2158+{
2159+ cns21xx_gec_write_phy(gec, port, 12, 0xd8ff);
2160+ eth3220ac_def_bpf(gec, port);
2161+}
2162+
2163+/*=============================================================*
2164+ * wp3220ac_phystate
2165+ *=============================================================*/
2166+static void wp3220ac_phystate(struct cns21xx_gec *gec, int port, int link, int speed)
2167+{
2168+ int next_state;
2169+ u16 reg, reg2;
2170+
2171+ phy[port].timer += ETH3220_PHY_MON_PERIOD;
2172+
2173+ if (link) {
2174+ /* Link up state */
2175+ switch (phy[port].state) {
2176+ case LINK_UP_POSITIVE:
2177+ next_state = eth3220ac_rt8100_check(gec, port) ?
2178+ WAIT_BYPASS_LINK_UP_POSITIVE :
2179+ LINK_UP_POSITIVE;
2180+ break;
2181+
2182+ case PHY_STATE_INIT:
2183+ case WAIT_LINK_UP_POSITIVE:
2184+ case LINK_DOWN_POSITIVE:
2185+ next_state = LINK_UP_POSITIVE;
2186+ eth3220ac_def_linkup_setting(gec, port);
2187+ eth3220ac_link_agc(gec, port, speed);
2188+ eth3220ac_release_bpf(gec, port);
2189+ break;
2190+
2191+ case WAIT_BYPASS_LINK_UP_POSITIVE:
2192+ case BYPASS_AND_LINK_UP_POSITIVE:
2193+ next_state = BYPASS_AND_LINK_UP_POSITIVE;
2194+ break;
2195+
2196+ case WAIT_8101_LINK_UP_POSITIVE:
2197+ next_state = LINK_UP_8101_POSITIVE;
2198+ eth3220ac_link_agc(gec, port, speed);
2199+ cns21xx_gec_write_phy(gec, port, 12, 0x98ff);
2200+ break;
2201+
2202+ case LINK_UP_8101_POSITIVE:
2203+ next_state = LINK_UP_8101_POSITIVE;
2204+ break;
2205+
2206+ default:
2207+ next_state = LINK_UP_POSITIVE;
2208+ eth3220ac_def_linkup_setting(gec, port);
2209+ eth3220ac_link_agc(gec, port, speed);
2210+ }
2211+ } else {
2212+ /* Link down state */
2213+ switch (phy[port].state) {
2214+ case LINK_DOWN_POSITIVE:
2215+ cns21xx_gec_read_phy(gec, port, 5, &reg);
2216+ cns21xx_gec_read_phy(gec, port, 28, &reg2);
2217+
2218+ /* AN Link Partner Ability Register or NLP */
2219+ if (reg || (reg2 & 0x100))
2220+ next_state = WAIT_LINK_UP_POSITIVE;
2221+ else
2222+ next_state = LINK_DOWN_POSITIVE;
2223+ break;
2224+
2225+ case WAIT_LINK_UP_POSITIVE:
2226+ if (phy[port].state_time >
2227+ LINK_DOWN_ABILITY_DETECT_TIMEOUT)
2228+ next_state = LINK_DOWN_POSITIVE;
2229+ else
2230+ next_state = WAIT_LINK_UP_POSITIVE;
2231+ break;
2232+
2233+ case WAIT_BYPASS_LINK_UP_POSITIVE:
2234+ /* set timeout = 5 sec */
2235+ if (phy[port].state_time >
2236+ WAIT_BYPASS_LINK_UP_POSITIVE_TIMEOUT) {
2237+ next_state = LINK_DOWN_POSITIVE;
2238+
2239+ /* Bypass Filter disable */
2240+ eth3220ac_rt8100_linkdown(gec, port);
2241+ eth3220ac_def_bpf(gec, port);
2242+ } else {
2243+ next_state = WAIT_BYPASS_LINK_UP_POSITIVE;
2244+ }
2245+ break;
2246+
2247+ case BYPASS_AND_LINK_UP_POSITIVE:
2248+ next_state = LINK_DOWN_POSITIVE;
2249+ eth3220ac_rt8100_linkdown(gec, port);
2250+ eth3220ac_def_bpf(gec, port);
2251+ break;
2252+
2253+ case WAIT_8101_LINK_UP_POSITIVE:
2254+ if (phy[port].state_time > WAIT_8101_LINK_UP_TIMEOUT) {
2255+ next_state = LINK_DOWN_POSITIVE;
2256+ eth3220ac_normal_phy_setting(gec, port);
2257+ eth3220ac_def_linkdown_setting(gec, port);
2258+ } else {
2259+ next_state = WAIT_8101_LINK_UP_POSITIVE;
2260+ }
2261+ break;
2262+
2263+ case LINK_UP_POSITIVE:
2264+ eth3220ac_unlink_agc(gec, port);
2265+ eth3220ac_def_linkdown_setting(gec, port);
2266+ eth3220ac_def_bpf(gec, port);
2267+ if (phy[port].timer > DETECT_8101_PERIOD) {
2268+ next_state = LINK_DOWN_POSITIVE;
2269+ phy[port].timer = 0;
2270+ phy[port].linkdown_cnt = 1;
2271+ } else {
2272+ if (++phy[port].linkdown_cnt > 2) {
2273+ next_state = WAIT_8101_LINK_UP_POSITIVE;
2274+ eth3220ac_rt8101_phy_setting(gec, port);
2275+ } else {
2276+ next_state = LINK_DOWN_POSITIVE;
2277+ }
2278+ }
2279+ break;
2280+
2281+ case LINK_UP_8101_POSITIVE:
2282+ eth3220ac_normal_phy_setting(gec, port);
2283+ /* fall down to phy normal state */
2284+ case PHY_STATE_INIT:
2285+ eth3220ac_def_linkdown_setting(gec, port);
2286+ eth3220ac_unlink_agc(gec, port);
2287+ default:
2288+ next_state = LINK_DOWN_POSITIVE;
2289+ }
2290+ }
2291+
2292+ if (phy[port].state != next_state) {
2293+ phy[port].state_time = 0;
2294+#if DEBUG_PHY_STATE_TRANSITION
2295+ if (debug_phy_port == -1 || port == debug_phy_port) {
2296+ if ((phy[port].state < PHY_STATE_LAST) &&
2297+ (next_state < PHY_STATE_LAST))
2298+ dev_dbg(&gec->netdev->dev,
2299+ "p%d: %s->%s, %d, %d\n",
2300+ port, phystate_name[phy[port].state],
2301+ phystate_name[next_state],
2302+ phy[port].timer,
2303+ phy[port].linkdown_cnt);
2304+ else
2305+ dev_dbg(&gec->netdev->dev,
2306+ "p%d: %d->%d\n",
2307+ port, phy[port].state, next_state);
2308+ }
2309+#endif /* DEBUG_PHY_STATE_TRANSITION */
2310+ } else {
2311+ phy[port].state_time += ETH3220_PHY_MON_PERIOD;
2312+ }
2313+ phy[port].state = next_state;
2314+}
2315+
2316+/*=============================================================*
2317+ * eth3220_phyinit:
2318+ *=============================================================*/
2319+static void eth3220ac_10m_agc(struct cns21xx_gec *gec)
2320+{
2321+ /* Force 10M AGC = 2c globally */
2322+ cns21xx_gec_write_phy(gec, 0, 31, 0x2f1a);
2323+ cns21xx_gec_write_phy(gec, 0, 12, 0x112c);
2324+ cns21xx_gec_write_phy(gec, 0, 13, 0x2e21);
2325+ cns21xx_gec_write_phy(gec, 0, 31, 0xaf1a);
2326+}
2327+
2328+static void eth3220ac_dfe_init(struct cns21xx_gec *gec)
2329+{
2330+ int i;
2331+
2332+ cns21xx_gec_write_phy(gec, 0, 31, 0x2f1a);
2333+ for (i = 0; i <= 7; i++)
2334+ cns21xx_gec_write_phy(gec, 0, i, 0);
2335+ cns21xx_gec_write_phy(gec, 0, 11, 0x0b50);
2336+ cns21xx_gec_write_phy(gec, 0, 31, 0xaf1a);
2337+}
2338+
2339+static void eth3220ac_phy_cdr_training_init(struct cns21xx_gec *gec)
2340+{
2341+ int i;
2342+
2343+ /* Force all port in 10M FD mode */
2344+ for (i = 0; i < NUM_PHY; i++)
2345+ cns21xx_gec_write_phy(gec, i, 0, 0x100);
2346+
2347+ /* Global setting */
2348+ cns21xx_gec_write_phy(gec, 0, 31, 0x2f1a);
2349+ cns21xx_gec_write_phy(gec, 0, 29, 0x5021);
2350+ udelay(2000); /* 2ms, wait > 1 ms */
2351+ cns21xx_gec_write_phy(gec, 0, 29, 0x4021);
2352+ udelay(2000); /* 2ms, wait > 1 ms */
2353+ cns21xx_gec_write_phy(gec, 0, 31, 0xaf1a);
2354+
2355+ /* Enable phy AN */
2356+ for (i = 0; i < NUM_PHY; i++)
2357+ cns21xx_gec_write_phy(gec, i, 0, 0x3100);
2358+}
2359+
2360+static void eth3220_phyinit(struct cns21xx_gec *gec)
2361+{
2362+ eth3220ac_10m_agc(gec);
2363+ eth3220ac_dfe_init(gec);
2364+ eth3220ac_phy_cdr_training_init(gec);
2365+}
2366+
2367+static void eth3220_phycfg(struct cns21xx_gec *gec, int phyaddr)
2368+{
2369+ eth3220ac_def_linkdown_setting(gec, phyaddr);
2370+ eth3220ac_normal_phy_setting(gec, phyaddr);
2371+ cns21xx_gec_write_phy(gec, phyaddr, 9, 0x7f);
2372+}
2373+
2374+static void internal_phy_patch_check(struct cns21xx_gec *gec, int init)
2375+{
2376+ u32 short_cable_agc_detect_count;
2377+ u32 link_status = 0, link_speed;
2378+ u32 phy_addr = gec->phy_addr;
2379+ u16 phy_data;
2380+ u16 phy_data2;
2381+ int i;
2382+
2383+ cns21xx_gec_read_phy(gec, phy_addr, 1, &phy_data);
2384+ udelay(100);
2385+ cns21xx_gec_read_phy(gec, phy_addr, 1, &phy_data2);
2386+ if (((phy_data & 0x0004) != 0x0004) &&
2387+ ((phy_data2 & 0x0004) != 0x0004)) {
2388+ /* link down */
2389+ short_cable_agc_detect_count = 0;
2390+ for (i = 0; i < INTERNAL_PHY_PATCH_CHECKCNT; i++) {
2391+ cns21xx_gec_read_phy(gec, phy_addr, 15, &phy_data);
2392+ udelay(1000);
2393+ if ((phy_data & 0x7F) <= 0x12) {
2394+ /* short cable */
2395+ short_cable_agc_detect_count++;
2396+ break;
2397+ }
2398+ }
2399+ if (short_cable_agc_detect_count) {
2400+ u32 mac_cfg;
2401+
2402+ /* short cable */
2403+ phy_statemachine = wp3220ac_phystate;
2404+ eth3220_phyinit(gec);
2405+ cns21xx_gec_read_phy(gec, phy_addr, 1, &phy_data);
2406+ if (phy_data & 0x0040)
2407+ link_status = 1;
2408+
2409+ mac_cfg = cns21xx_gec_rr(gec, GEC_REG_MAC_CFG);
2410+ if ((mac_cfg & 0xC) == 0x4) /* 100Mbps */
2411+ link_speed = 1;
2412+ else
2413+ link_speed = 0;
2414+
2415+ link_status_old = link_status;
2416+ for (i = 0; i < MAX_PHY_PORT; link_status >>= 1, i++)
2417+ eth3220_phycfg(gec, i);
2418+ } else {
2419+ /* long cable */
2420+ /* set to global domain */
2421+ cns21xx_gec_write_phy(gec, phy_addr, 31,
2422+ 0x2f1a);
2423+ for (i = 0; i < 32; i++)
2424+ cns21xx_gec_write_phy(gec, phy_addr, i,
2425+ long_cable_global_reg[i]);
2426+
2427+ /* set to local domain */
2428+ cns21xx_gec_write_phy(gec, phy_addr, 31,
2429+ 0xaf1a);
2430+ for (i = 0; i < 32; i++)
2431+ cns21xx_gec_write_phy(gec, phy_addr, i,
2432+ long_cable_local_reg[i]);
2433+ }
2434+ }
2435+}
2436+
2437+static void internal_phy_timer_func(unsigned long data)
2438+{
2439+ struct cns21xx_gec *gec = (struct cns21xx_gec *) data;
2440+
2441+ internal_phy_patch_check(gec, 0);
2442+ mod_timer(&gec->internal_phy_timer,
2443+ jiffies + INTERNAL_PHY_PATCH_CHECK_PERIOD / 10);
2444+}
2445+
2446+static void internal_phy_init_timer(struct cns21xx_gec *gec)
2447+{
2448+ init_timer(&gec->internal_phy_timer);
2449+ gec->internal_phy_timer.function = internal_phy_timer_func;
2450+ gec->internal_phy_timer.data = (unsigned long) gec;
2451+}
2452+
2453+static void internal_phy_start_timer(struct cns21xx_gec *gec)
2454+{
2455+ dev_dbg(&gec->netdev->dev, "starting patch check.\n");
2456+
2457+ internal_phy_patch_check(gec, 1);
2458+ mod_timer(&gec->internal_phy_timer,
2459+ jiffies + INTERNAL_PHY_PATCH_CHECK_PERIOD / 10);
2460+}
2461+
2462+static void internal_phy_stop_timer(struct cns21xx_gec *gec)
2463+{
2464+ dev_dbg(&gec->netdev->dev, "stopping patch check.\n");
2465+
2466+ del_timer_sync(&gec->internal_phy_timer);
2467+}
2468--- /dev/null
2469+++ b/drivers/net/ethernet/cns21xx/Kconfig
2470@@ -0,0 +1,7 @@
2471+config CNS21XX_GEC
2472+ tristate "CNS21XX Gigabit Ethernet Controller support"
2473+ depends on ARCH_CNS21XX
2474+ help
2475+ If you wish to compile a kernel for Cavium Networks CNS21XX
2476+ with ethernet support, then you should always answer Y to this.
2477+
2478--- /dev/null
2479+++ b/drivers/net/ethernet/cns21xx/Makefile
2480@@ -0,0 +1,7 @@
2481+#
2482+# Makefile for the Cavium Networks CNS21XX ethernet driver
2483+#
2484+
2485+cns21xx_gec-y += cns21xx_gec_main.o
2486+
2487+obj-$(CONFIG_CNS21XX_GEC) += cns21xx_gec.o
2488--- a/drivers/net/ethernet/Kconfig
2489+++ b/drivers/net/ethernet/Kconfig
2490@@ -32,6 +32,7 @@ source "drivers/net/ethernet/calxeda/Kco
2491 source "drivers/net/ethernet/chelsio/Kconfig"
2492 source "drivers/net/ethernet/cirrus/Kconfig"
2493 source "drivers/net/ethernet/cisco/Kconfig"
2494+source "drivers/net/ethernet/cns21xx/Kconfig"
2495 source "drivers/net/ethernet/davicom/Kconfig"
2496 
2497 config DNET
2498--- a/drivers/net/ethernet/Makefile
2499+++ b/drivers/net/ethernet/Makefile
2500@@ -18,6 +18,7 @@ obj-$(CONFIG_NET_CALXEDA_XGMAC) += calxe
2501 obj-$(CONFIG_NET_VENDOR_CHELSIO) += chelsio/
2502 obj-$(CONFIG_NET_VENDOR_CIRRUS) += cirrus/
2503 obj-$(CONFIG_NET_VENDOR_CISCO) += cisco/
2504+obj-$(CONFIG_CNS21XX_GEC) += cns21xx/
2505 obj-$(CONFIG_DM9000) += davicom/
2506 obj-$(CONFIG_DNET) += dnet.o
2507 obj-$(CONFIG_NET_VENDOR_DEC) += dec/
2508

Archive Download this file



interactive