Root/target/linux/cns3xxx/patches-3.3/051-cns3xxx_gigabit.patch

1--- /dev/null
2+++ b/drivers/net/ethernet/cavium/cns3xxx_eth.c
3@@ -0,0 +1,1298 @@
4+/*
5+ * Cavium CNS3xxx Gigabit driver for Linux
6+ *
7+ * Copyright 2011 Gateworks Corporation
8+ * Chris Lang <clang@gateworks.com>
9+ *
10+ * This program is free software; you can redistribute it and/or modify it
11+ * under the terms of version 2 of the GNU General Public License
12+ * as published by the Free Software Foundation.
13+ *
14+ */
15+
16+#include <linux/delay.h>
17+#include <linux/module.h>
18+#include <linux/dma-mapping.h>
19+#include <linux/dmapool.h>
20+#include <linux/etherdevice.h>
21+#include <linux/interrupt.h>
22+#include <linux/io.h>
23+#include <linux/kernel.h>
24+#include <linux/phy.h>
25+#include <linux/platform_device.h>
26+#include <linux/skbuff.h>
27+#include <mach/irqs.h>
28+#include <mach/platform.h>
29+
30+#define DRV_NAME "cns3xxx_eth"
31+
32+#define RX_DESCS 512
33+#define TX_DESCS 512
34+#define SKB_DMA_REALIGN ((PAGE_SIZE - NET_SKB_PAD) % SMP_CACHE_BYTES)
35+
36+#define RX_POOL_ALLOC_SIZE (sizeof(struct rx_desc) * RX_DESCS)
37+#define TX_POOL_ALLOC_SIZE (sizeof(struct tx_desc) * TX_DESCS)
38+#define REGS_SIZE 336
39+#define MAX_MRU (1536 + SKB_DMA_REALIGN)
40+#define CNS3XXX_MAX_MTU (1536)
41+
42+#define NAPI_WEIGHT 64
43+
44+/* MDIO Defines */
45+#define MDIO_CMD_COMPLETE 0x00008000
46+#define MDIO_WRITE_COMMAND 0x00002000
47+#define MDIO_READ_COMMAND 0x00004000
48+#define MDIO_REG_OFFSET 8
49+#define MDIO_VALUE_OFFSET 16
50+
51+/* Descritor Defines */
52+#define END_OF_RING 0x40000000
53+#define FIRST_SEGMENT 0x20000000
54+#define LAST_SEGMENT 0x10000000
55+#define FORCE_ROUTE 0x04000000
56+#define IP_CHECKSUM 0x00040000
57+#define UDP_CHECKSUM 0x00020000
58+#define TCP_CHECKSUM 0x00010000
59+
60+/* Port Config Defines */
61+#define PORT_BP_ENABLE 0x00020000
62+#define PORT_DISABLE 0x00040000
63+#define PORT_LEARN_DIS 0x00080000
64+#define PORT_BLOCK_STATE 0x00100000
65+#define PORT_BLOCK_MODE 0x00200000
66+
67+#define PROMISC_OFFSET 29
68+
69+/* Global Config Defines */
70+#define UNKNOWN_VLAN_TO_CPU 0x02000000
71+#define ACCEPT_CRC_PACKET 0x00200000
72+#define CRC_STRIPPING 0x00100000
73+
74+/* VLAN Config Defines */
75+#define NIC_MODE 0x00008000
76+#define VLAN_UNAWARE 0x00000001
77+
78+/* DMA AUTO Poll Defines */
79+#define TS_POLL_EN 0x00000020
80+#define TS_SUSPEND 0x00000010
81+#define FS_POLL_EN 0x00000002
82+#define FS_SUSPEND 0x00000001
83+
84+/* DMA Ring Control Defines */
85+#define QUEUE_THRESHOLD 0x000000f0
86+#define CLR_FS_STATE 0x80000000
87+
88+/* Interrupt Status Defines */
89+#define MAC0_STATUS_CHANGE 0x00004000
90+#define MAC1_STATUS_CHANGE 0x00008000
91+#define MAC2_STATUS_CHANGE 0x00010000
92+#define MAC0_RX_ERROR 0x00100000
93+#define MAC1_RX_ERROR 0x00200000
94+#define MAC2_RX_ERROR 0x00400000
95+
96+struct tx_desc
97+{
98+ u32 sdp; /* segment data pointer */
99+
100+ union {
101+ struct {
102+ u32 sdl:16; /* segment data length */
103+ u32 tco:1;
104+ u32 uco:1;
105+ u32 ico:1;
106+ u32 rsv_1:3; /* reserve */
107+ u32 pri:3;
108+ u32 fp:1; /* force priority */
109+ u32 fr:1;
110+ u32 interrupt:1;
111+ u32 lsd:1;
112+ u32 fsd:1;
113+ u32 eor:1;
114+ u32 cown:1;
115+ };
116+ u32 config0;
117+ };
118+
119+ union {
120+ struct {
121+ u32 ctv:1;
122+ u32 stv:1;
123+ u32 sid:4;
124+ u32 inss:1;
125+ u32 dels:1;
126+ u32 rsv_2:9;
127+ u32 pmap:5;
128+ u32 mark:3;
129+ u32 ewan:1;
130+ u32 fewan:1;
131+ u32 rsv_3:5;
132+ };
133+ u32 config1;
134+ };
135+
136+ union {
137+ struct {
138+ u32 c_vid:12;
139+ u32 c_cfs:1;
140+ u32 c_pri:3;
141+ u32 s_vid:12;
142+ u32 s_dei:1;
143+ u32 s_pri:3;
144+ };
145+ u32 config2;
146+ };
147+
148+ u8 alignment[16]; /* for 32 byte */
149+};
150+
151+struct rx_desc
152+{
153+ u32 sdp; /* segment data pointer */
154+
155+ union {
156+ struct {
157+ u32 sdl:16; /* segment data length */
158+ u32 l4f:1;
159+ u32 ipf:1;
160+ u32 prot:4;
161+ u32 hr:6;
162+ u32 lsd:1;
163+ u32 fsd:1;
164+ u32 eor:1;
165+ u32 cown:1;
166+ };
167+ u32 config0;
168+ };
169+
170+ union {
171+ struct {
172+ u32 ctv:1;
173+ u32 stv:1;
174+ u32 unv:1;
175+ u32 iwan:1;
176+ u32 exdv:1;
177+ u32 e_wan:1;
178+ u32 rsv_1:2;
179+ u32 sp:3;
180+ u32 crc_err:1;
181+ u32 un_eth:1;
182+ u32 tc:2;
183+ u32 rsv_2:1;
184+ u32 ip_offset:5;
185+ u32 rsv_3:11;
186+ };
187+ u32 config1;
188+ };
189+
190+ union {
191+ struct {
192+ u32 c_vid:12;
193+ u32 c_cfs:1;
194+ u32 c_pri:3;
195+ u32 s_vid:12;
196+ u32 s_dei:1;
197+ u32 s_pri:3;
198+ };
199+ u32 config2;
200+ };
201+
202+ u8 alignment[16]; /* for 32 byte alignment */
203+};
204+
205+
206+struct switch_regs {
207+ u32 phy_control;
208+ u32 phy_auto_addr;
209+ u32 mac_glob_cfg;
210+ u32 mac_cfg[4];
211+ u32 mac_pri_ctrl[5], __res;
212+ u32 etype[2];
213+ u32 udp_range[4];
214+ u32 prio_etype_udp;
215+ u32 prio_ipdscp[8];
216+ u32 tc_ctrl;
217+ u32 rate_ctrl;
218+ u32 fc_glob_thrs;
219+ u32 fc_port_thrs;
220+ u32 mc_fc_glob_thrs;
221+ u32 dc_glob_thrs;
222+ u32 arl_vlan_cmd;
223+ u32 arl_ctrl[3];
224+ u32 vlan_cfg;
225+ u32 pvid[2];
226+ u32 vlan_ctrl[3];
227+ u32 session_id[8];
228+ u32 intr_stat;
229+ u32 intr_mask;
230+ u32 sram_test;
231+ u32 mem_queue;
232+ u32 farl_ctrl;
233+ u32 fc_input_thrs, __res1[2];
234+ u32 clk_skew_ctrl;
235+ u32 mac_glob_cfg_ext, __res2[2];
236+ u32 dma_ring_ctrl;
237+ u32 dma_auto_poll_cfg;
238+ u32 delay_intr_cfg, __res3;
239+ u32 ts_dma_ctrl0;
240+ u32 ts_desc_ptr0;
241+ u32 ts_desc_base_addr0, __res4;
242+ u32 fs_dma_ctrl0;
243+ u32 fs_desc_ptr0;
244+ u32 fs_desc_base_addr0, __res5;
245+ u32 ts_dma_ctrl1;
246+ u32 ts_desc_ptr1;
247+ u32 ts_desc_base_addr1, __res6;
248+ u32 fs_dma_ctrl1;
249+ u32 fs_desc_ptr1;
250+ u32 fs_desc_base_addr1;
251+ u32 __res7[109];
252+ u32 mac_counter0[13];
253+};
254+
255+struct _tx_ring {
256+ struct tx_desc *desc;
257+ dma_addr_t phys_addr;
258+ struct tx_desc *cur_addr;
259+ struct sk_buff *buff_tab[TX_DESCS];
260+ unsigned int phys_tab[TX_DESCS];
261+ u32 free_index;
262+ u32 count_index;
263+ u32 cur_index;
264+ int num_used;
265+ int num_count;
266+};
267+
268+struct _rx_ring {
269+ struct rx_desc *desc;
270+ dma_addr_t phys_addr;
271+ struct rx_desc *cur_addr;
272+ struct sk_buff *buff_tab[RX_DESCS];
273+ unsigned int phys_tab[RX_DESCS];
274+ u32 cur_index;
275+ u32 alloc_index;
276+ int alloc_count;
277+};
278+
279+struct sw {
280+ struct resource *mem_res;
281+ struct switch_regs __iomem *regs;
282+ struct napi_struct napi;
283+ struct cns3xxx_plat_info *plat;
284+ struct _tx_ring *tx_ring;
285+ struct _rx_ring *rx_ring;
286+};
287+
288+struct port {
289+ struct net_device *netdev;
290+ struct phy_device *phydev;
291+ struct sw *sw;
292+ int id; /* logical port ID */
293+ int speed, duplex;
294+};
295+
296+static spinlock_t mdio_lock;
297+static DEFINE_SPINLOCK(tx_lock);
298+static struct switch_regs __iomem *mdio_regs; /* mdio command and status only */
299+struct mii_bus *mdio_bus;
300+static int ports_open;
301+static struct port *switch_port_tab[4];
302+static struct dma_pool *rx_dma_pool;
303+static struct dma_pool *tx_dma_pool;
304+struct net_device *napi_dev;
305+
306+static int cns3xxx_mdio_cmd(struct mii_bus *bus, int phy_id, int location,
307+ int write, u16 cmd)
308+{
309+ int cycles = 0;
310+ u32 temp = 0;
311+
312+ temp = __raw_readl(&mdio_regs->phy_control);
313+ temp |= MDIO_CMD_COMPLETE;
314+ __raw_writel(temp, &mdio_regs->phy_control);
315+ udelay(10);
316+
317+ if (write) {
318+ temp = (cmd << MDIO_VALUE_OFFSET);
319+ temp |= MDIO_WRITE_COMMAND;
320+ } else {
321+ temp = MDIO_READ_COMMAND;
322+ }
323+ temp |= ((location & 0x1f) << MDIO_REG_OFFSET);
324+ temp |= (phy_id & 0x1f);
325+
326+ __raw_writel(temp, &mdio_regs->phy_control);
327+
328+ while (((__raw_readl(&mdio_regs->phy_control) & MDIO_CMD_COMPLETE) == 0)
329+ && cycles < 5000) {
330+ udelay(1);
331+ cycles++;
332+ }
333+
334+ if (cycles == 5000) {
335+ printk(KERN_ERR "%s #%i: MII transaction failed\n", bus->name,
336+ phy_id);
337+ return -1;
338+ }
339+
340+ temp = __raw_readl(&mdio_regs->phy_control);
341+ temp |= MDIO_CMD_COMPLETE;
342+ __raw_writel(temp, &mdio_regs->phy_control);
343+
344+ if (write)
345+ return 0;
346+
347+ return ((temp >> MDIO_VALUE_OFFSET) & 0xFFFF);
348+}
349+
350+static int cns3xxx_mdio_read(struct mii_bus *bus, int phy_id, int location)
351+{
352+ unsigned long flags;
353+ int ret;
354+
355+ spin_lock_irqsave(&mdio_lock, flags);
356+ ret = cns3xxx_mdio_cmd(bus, phy_id, location, 0, 0);
357+ spin_unlock_irqrestore(&mdio_lock, flags);
358+ return ret;
359+}
360+
361+static int cns3xxx_mdio_write(struct mii_bus *bus, int phy_id, int location,
362+ u16 val)
363+{
364+ unsigned long flags;
365+ int ret;
366+
367+ spin_lock_irqsave(&mdio_lock, flags);
368+ ret = cns3xxx_mdio_cmd(bus, phy_id, location, 1, val);
369+ spin_unlock_irqrestore(&mdio_lock, flags);
370+ return ret;
371+}
372+
373+static int cns3xxx_mdio_register(void)
374+{
375+ int err;
376+
377+ if (!(mdio_bus = mdiobus_alloc()))
378+ return -ENOMEM;
379+
380+ mdio_regs = (struct switch_regs __iomem *)CNS3XXX_SWITCH_BASE_VIRT;
381+
382+ spin_lock_init(&mdio_lock);
383+ mdio_bus->name = "CNS3xxx MII Bus";
384+ mdio_bus->read = &cns3xxx_mdio_read;
385+ mdio_bus->write = &cns3xxx_mdio_write;
386+ strcpy(mdio_bus->id, "0");
387+
388+ if ((err = mdiobus_register(mdio_bus)))
389+ mdiobus_free(mdio_bus);
390+ return err;
391+}
392+
393+static void cns3xxx_mdio_remove(void)
394+{
395+ mdiobus_unregister(mdio_bus);
396+ mdiobus_free(mdio_bus);
397+}
398+
399+static void enable_tx_dma(struct sw *sw)
400+{
401+ __raw_writel(0x1, &sw->regs->ts_dma_ctrl0);
402+}
403+
404+static void enable_rx_dma(struct sw *sw)
405+{
406+ __raw_writel(0x1, &sw->regs->fs_dma_ctrl0);
407+}
408+
409+static void cns3xxx_adjust_link(struct net_device *dev)
410+{
411+ struct port *port = netdev_priv(dev);
412+ struct phy_device *phydev = port->phydev;
413+
414+ if (!phydev->link) {
415+ if (port->speed) {
416+ port->speed = 0;
417+ printk(KERN_INFO "%s: link down\n", dev->name);
418+ }
419+ return;
420+ }
421+
422+ if (port->speed == phydev->speed && port->duplex == phydev->duplex)
423+ return;
424+
425+ port->speed = phydev->speed;
426+ port->duplex = phydev->duplex;
427+
428+ printk(KERN_INFO "%s: link up, speed %u Mb/s, %s duplex\n",
429+ dev->name, port->speed, port->duplex ? "full" : "half");
430+}
431+
432+irqreturn_t eth_rx_irq(int irq, void *pdev)
433+{
434+ struct net_device *dev = pdev;
435+ struct sw *sw = netdev_priv(dev);
436+ if (likely(napi_schedule_prep(&sw->napi))) {
437+ disable_irq_nosync(IRQ_CNS3XXX_SW_R0RXC);
438+ __napi_schedule(&sw->napi);
439+ }
440+ return (IRQ_HANDLED);
441+}
442+
443+irqreturn_t eth_stat_irq(int irq, void *pdev)
444+{
445+ struct net_device *dev = pdev;
446+ struct sw *sw = netdev_priv(dev);
447+ u32 cfg;
448+ u32 stat = __raw_readl(&sw->regs->intr_stat);
449+ __raw_writel(0xffffffff, &sw->regs->intr_stat);
450+
451+ if (stat & MAC2_RX_ERROR)
452+ switch_port_tab[3]->netdev->stats.rx_dropped++;
453+ if (stat & MAC1_RX_ERROR)
454+ switch_port_tab[1]->netdev->stats.rx_dropped++;
455+ if (stat & MAC0_RX_ERROR)
456+ switch_port_tab[0]->netdev->stats.rx_dropped++;
457+
458+ if (stat & MAC0_STATUS_CHANGE) {
459+ cfg = __raw_readl(&sw->regs->mac_cfg[0]);
460+ switch_port_tab[0]->phydev->link = (cfg & 0x1);
461+ switch_port_tab[0]->phydev->duplex = ((cfg >> 4) & 0x1);
462+ if (((cfg >> 2) & 0x3) == 2)
463+ switch_port_tab[0]->phydev->speed = 1000;
464+ else if (((cfg >> 2) & 0x3) == 1)
465+ switch_port_tab[0]->phydev->speed = 100;
466+ else
467+ switch_port_tab[0]->phydev->speed = 10;
468+ cns3xxx_adjust_link(switch_port_tab[0]->netdev);
469+ }
470+
471+ if (stat & MAC1_STATUS_CHANGE) {
472+ cfg = __raw_readl(&sw->regs->mac_cfg[1]);
473+ switch_port_tab[1]->phydev->link = (cfg & 0x1);
474+ switch_port_tab[1]->phydev->duplex = ((cfg >> 4) & 0x1);
475+ if (((cfg >> 2) & 0x3) == 2)
476+ switch_port_tab[1]->phydev->speed = 1000;
477+ else if (((cfg >> 2) & 0x3) == 1)
478+ switch_port_tab[1]->phydev->speed = 100;
479+ else
480+ switch_port_tab[1]->phydev->speed = 10;
481+ cns3xxx_adjust_link(switch_port_tab[1]->netdev);
482+ }
483+
484+ if (stat & MAC2_STATUS_CHANGE) {
485+ cfg = __raw_readl(&sw->regs->mac_cfg[3]);
486+ switch_port_tab[3]->phydev->link = (cfg & 0x1);
487+ switch_port_tab[3]->phydev->duplex = ((cfg >> 4) & 0x1);
488+ if (((cfg >> 2) & 0x3) == 2)
489+ switch_port_tab[3]->phydev->speed = 1000;
490+ else if (((cfg >> 2) & 0x3) == 1)
491+ switch_port_tab[3]->phydev->speed = 100;
492+ else
493+ switch_port_tab[3]->phydev->speed = 10;
494+ cns3xxx_adjust_link(switch_port_tab[3]->netdev);
495+ }
496+
497+ return (IRQ_HANDLED);
498+}
499+
500+
501+static void cns3xxx_alloc_rx_buf(struct sw *sw, int received)
502+{
503+ struct _rx_ring *rx_ring = sw->rx_ring;
504+ unsigned int i = rx_ring->alloc_index;
505+ struct rx_desc *desc = &(rx_ring)->desc[i];
506+ struct sk_buff *skb;
507+ unsigned int phys;
508+
509+ for (received += rx_ring->alloc_count; received > 0; received--) {
510+ if ((skb = dev_alloc_skb(MAX_MRU))) {
511+ if (SKB_DMA_REALIGN)
512+ skb_reserve(skb, SKB_DMA_REALIGN);
513+ skb_reserve(skb, NET_IP_ALIGN);
514+ phys = dma_map_single(NULL, skb->data,
515+ CNS3XXX_MAX_MTU, DMA_FROM_DEVICE);
516+ if (dma_mapping_error(NULL, phys)) {
517+ dev_kfree_skb(skb);
518+ /* Failed to map, better luck next time */
519+ goto out;;
520+ }
521+ desc->sdp = phys;
522+ } else {
523+ /* Failed to allocate skb, try again next time */
524+ goto out;
525+ }
526+
527+ /* put the new buffer on RX-free queue */
528+ rx_ring->buff_tab[i] = skb;
529+ rx_ring->phys_tab[i] = phys;
530+ if (i == RX_DESCS - 1) {
531+ i = 0;
532+ desc->config0 = END_OF_RING | FIRST_SEGMENT |
533+ LAST_SEGMENT | CNS3XXX_MAX_MTU;
534+ desc = &(rx_ring)->desc[i];
535+ } else {
536+ desc->config0 = FIRST_SEGMENT | LAST_SEGMENT | CNS3XXX_MAX_MTU;
537+ i++;
538+ desc++;
539+ }
540+ }
541+out:
542+ rx_ring->alloc_count = received;
543+ rx_ring->alloc_index = i;
544+}
545+
546+static void clear_tx_desc(struct sw *sw)
547+{
548+ struct _tx_ring *tx_ring = sw->tx_ring;
549+ struct tx_desc *desc;
550+ int i;
551+ int index;
552+ int num_used = tx_ring->num_used;
553+ struct sk_buff *skb;
554+
555+ if (num_used < (TX_DESCS >> 1))
556+ return;
557+
558+ index = tx_ring->free_index;
559+ desc = &(tx_ring)->desc[index];
560+ for (i = 0; i < num_used; i++) {
561+ if (desc->cown) {
562+ skb = tx_ring->buff_tab[index];
563+ tx_ring->buff_tab[index] = 0;
564+ if (skb)
565+ dev_kfree_skb_any(skb);
566+ dma_unmap_single(NULL, tx_ring->phys_tab[index],
567+ desc->sdl, DMA_TO_DEVICE);
568+ if (++index == TX_DESCS) {
569+ index = 0;
570+ desc = &(tx_ring)->desc[index];
571+ } else {
572+ desc++;
573+ }
574+ } else {
575+ break;
576+ }
577+ }
578+ tx_ring->free_index = index;
579+ tx_ring->num_used -= i;
580+}
581+
582+static int eth_poll(struct napi_struct *napi, int budget)
583+{
584+ struct sw *sw = container_of(napi, struct sw, napi);
585+ struct net_device *dev;
586+ struct _rx_ring *rx_ring = sw->rx_ring;
587+ int received = 0;
588+ unsigned int length;
589+ unsigned int i = rx_ring->cur_index;
590+ struct rx_desc *desc = &(rx_ring)->desc[i];
591+
592+ while (desc->cown) {
593+ struct sk_buff *skb;
594+
595+ if (received >= budget)
596+ break;
597+
598+ skb = rx_ring->buff_tab[i];
599+
600+ dev = switch_port_tab[desc->sp]->netdev;
601+
602+ length = desc->sdl;
603+ /* process received frame */
604+ dma_unmap_single(&dev->dev, rx_ring->phys_tab[i],
605+ length, DMA_FROM_DEVICE);
606+
607+ skb_put(skb, length);
608+
609+ skb->dev = dev;
610+ skb->protocol = eth_type_trans(skb, dev);
611+
612+ dev->stats.rx_packets++;
613+ dev->stats.rx_bytes += length;
614+
615+ /* RX Hardware checksum offload */
616+ switch (desc->prot) {
617+ case 1:
618+ case 2:
619+ case 5:
620+ case 6:
621+ case 13:
622+ case 14:
623+ if (desc->l4f)
624+ skb->ip_summed = CHECKSUM_NONE;
625+ else
626+ skb->ip_summed = CHECKSUM_UNNECESSARY;
627+ break;
628+ default:
629+ skb->ip_summed = CHECKSUM_NONE;
630+ break;
631+ }
632+
633+ napi_gro_receive(napi, skb);
634+
635+ received++;
636+
637+ if (++i == RX_DESCS) {
638+ i = 0;
639+ desc = &(rx_ring)->desc[i];
640+ } else {
641+ desc++;
642+ }
643+ }
644+
645+ cns3xxx_alloc_rx_buf(sw, received);
646+
647+ rx_ring->cur_index = i;
648+
649+ if (received != budget) {
650+ napi_complete(napi);
651+ enable_irq(IRQ_CNS3XXX_SW_R0RXC);
652+ }
653+
654+ enable_rx_dma(sw);
655+
656+ return received;
657+}
658+
659+static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
660+{
661+ struct port *port = netdev_priv(dev);
662+ struct sw *sw = port->sw;
663+ struct _tx_ring *tx_ring = sw->tx_ring;
664+ struct tx_desc *tx_desc;
665+ int index;
666+ int len;
667+ char pmap = (1 << port->id);
668+ unsigned int phys;
669+ int nr_frags = skb_shinfo(skb)->nr_frags;
670+ struct skb_frag_struct *frag;
671+ unsigned int i;
672+
673+ if (pmap == 8)
674+ pmap = (1 << 4);
675+
676+ if (skb->len > CNS3XXX_MAX_MTU) {
677+ dev_kfree_skb(skb);
678+ dev->stats.tx_errors++;
679+ return NETDEV_TX_OK;
680+ }
681+
682+ spin_lock(&tx_lock);
683+
684+ if ((tx_ring->num_used + nr_frags) >= TX_DESCS) {
685+ clear_tx_desc(sw);
686+ if ((tx_ring->num_used + nr_frags) >= TX_DESCS) {
687+ spin_unlock(&tx_lock);
688+ return NETDEV_TX_BUSY;
689+ }
690+ }
691+
692+ index = tx_ring->cur_index;
693+ tx_ring->cur_index = ((tx_ring->cur_index + nr_frags + 1) % TX_DESCS);
694+
695+ spin_unlock(&tx_lock);
696+
697+ if (!nr_frags) {
698+ tx_desc = &(tx_ring)->desc[index];
699+
700+ len = skb->len;
701+
702+ phys = dma_map_single(NULL, skb->data, len,
703+ DMA_TO_DEVICE);
704+
705+ tx_desc->sdp = phys;
706+ tx_desc->pmap = pmap;
707+ tx_ring->phys_tab[index] = phys;
708+
709+ tx_ring->buff_tab[index] = skb;
710+ if (index == TX_DESCS - 1) {
711+ tx_desc->config0 = END_OF_RING | FIRST_SEGMENT | LAST_SEGMENT |
712+ FORCE_ROUTE | IP_CHECKSUM | UDP_CHECKSUM |
713+ TCP_CHECKSUM | len;
714+ } else {
715+ tx_desc->config0 = FIRST_SEGMENT | LAST_SEGMENT |
716+ FORCE_ROUTE | IP_CHECKSUM | UDP_CHECKSUM |
717+ TCP_CHECKSUM | len;
718+ }
719+ } else {
720+ unsigned int config;
721+
722+ index = ((index + nr_frags) % TX_DESCS);
723+ tx_desc = &(tx_ring)->desc[index];
724+
725+ /* fragments */
726+ for (i = nr_frags; i > 0; i--) {
727+ void *addr;
728+
729+ frag = &skb_shinfo(skb)->frags[i-1];
730+ len = frag->size;
731+
732+ addr = page_address(skb_frag_page(frag)) +
733+ frag->page_offset;
734+ phys = dma_map_single(NULL, addr, len, DMA_TO_DEVICE);
735+
736+ tx_desc->sdp = phys;
737+
738+ tx_desc->pmap = pmap;
739+ tx_ring->phys_tab[index] = phys;
740+
741+ config = FORCE_ROUTE | IP_CHECKSUM | UDP_CHECKSUM |
742+ TCP_CHECKSUM | len;
743+ if (i == nr_frags) {
744+ config |= LAST_SEGMENT;
745+ tx_ring->buff_tab[index] = skb;
746+ }
747+ if (index == TX_DESCS - 1)
748+ config |= END_OF_RING;
749+ tx_desc->config0 = config;
750+
751+ if (index == 0) {
752+ index = TX_DESCS - 1;
753+ tx_desc = &(tx_ring)->desc[index];
754+ } else {
755+ index--;
756+ tx_desc--;
757+ }
758+ }
759+
760+ /* header */
761+ len = skb->len - skb->data_len;
762+
763+ phys = dma_map_single(NULL, skb->data, len,
764+ DMA_TO_DEVICE);
765+
766+ tx_desc->sdp = phys;
767+ tx_desc->pmap = pmap;
768+ tx_ring->phys_tab[index] = phys;
769+
770+ if (index == TX_DESCS - 1) {
771+ tx_desc->config0 = END_OF_RING | FIRST_SEGMENT |
772+ FORCE_ROUTE | IP_CHECKSUM | UDP_CHECKSUM |
773+ TCP_CHECKSUM | len;
774+ } else {
775+ tx_desc->config0 = FIRST_SEGMENT |
776+ FORCE_ROUTE | IP_CHECKSUM | UDP_CHECKSUM |
777+ TCP_CHECKSUM | len;
778+ }
779+ }
780+
781+ mb();
782+
783+ spin_lock(&tx_lock);
784+ tx_ring->num_used += nr_frags + 1;
785+ spin_unlock(&tx_lock);
786+
787+ dev->stats.tx_packets++;
788+ dev->stats.tx_bytes += skb->len;
789+
790+ enable_tx_dma(sw);
791+
792+ return NETDEV_TX_OK;
793+}
794+
795+static int eth_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
796+{
797+ struct port *port = netdev_priv(dev);
798+
799+ if (!netif_running(dev))
800+ return -EINVAL;
801+ return phy_mii_ioctl(port->phydev, req, cmd);
802+}
803+
804+/* ethtool support */
805+
806+static void cns3xxx_get_drvinfo(struct net_device *dev,
807+ struct ethtool_drvinfo *info)
808+{
809+ strcpy(info->driver, DRV_NAME);
810+ strcpy(info->bus_info, "internal");
811+}
812+
813+static int cns3xxx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
814+{
815+ struct port *port = netdev_priv(dev);
816+ return phy_ethtool_gset(port->phydev, cmd);
817+}
818+
819+static int cns3xxx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
820+{
821+ struct port *port = netdev_priv(dev);
822+ return phy_ethtool_sset(port->phydev, cmd);
823+}
824+
825+static int cns3xxx_nway_reset(struct net_device *dev)
826+{
827+ struct port *port = netdev_priv(dev);
828+ return phy_start_aneg(port->phydev);
829+}
830+
831+static struct ethtool_ops cns3xxx_ethtool_ops = {
832+ .get_drvinfo = cns3xxx_get_drvinfo,
833+ .get_settings = cns3xxx_get_settings,
834+ .set_settings = cns3xxx_set_settings,
835+ .nway_reset = cns3xxx_nway_reset,
836+ .get_link = ethtool_op_get_link,
837+};
838+
839+
840+static int init_rings(struct sw *sw)
841+{
842+ int i;
843+ struct _rx_ring *rx_ring = sw->rx_ring;
844+ struct _tx_ring *tx_ring = sw->tx_ring;
845+
846+ __raw_writel(0, &sw->regs->fs_dma_ctrl0);
847+ __raw_writel(TS_SUSPEND | FS_SUSPEND, &sw->regs->dma_auto_poll_cfg);
848+ __raw_writel(QUEUE_THRESHOLD, &sw->regs->dma_ring_ctrl);
849+ __raw_writel(CLR_FS_STATE | QUEUE_THRESHOLD, &sw->regs->dma_ring_ctrl);
850+
851+ __raw_writel(QUEUE_THRESHOLD, &sw->regs->dma_ring_ctrl);
852+
853+ if (!(rx_dma_pool = dma_pool_create(DRV_NAME, NULL,
854+ RX_POOL_ALLOC_SIZE, 32, 0)))
855+ return -ENOMEM;
856+
857+ if (!(rx_ring->desc = dma_pool_alloc(rx_dma_pool, GFP_KERNEL,
858+ &rx_ring->phys_addr)))
859+ return -ENOMEM;
860+ memset(rx_ring->desc, 0, RX_POOL_ALLOC_SIZE);
861+
862+ /* Setup RX buffers */
863+ for (i = 0; i < RX_DESCS; i++) {
864+ struct rx_desc *desc = &(rx_ring)->desc[i];
865+ struct sk_buff *skb;
866+ if (!(skb = dev_alloc_skb(MAX_MRU)))
867+ return -ENOMEM;
868+ if (SKB_DMA_REALIGN)
869+ skb_reserve(skb, SKB_DMA_REALIGN);
870+ skb_reserve(skb, NET_IP_ALIGN);
871+ desc->sdl = CNS3XXX_MAX_MTU;
872+ if (i == (RX_DESCS - 1))
873+ desc->eor = 1;
874+ desc->fsd = 1;
875+ desc->lsd = 1;
876+
877+ desc->sdp = dma_map_single(NULL, skb->data,
878+ CNS3XXX_MAX_MTU, DMA_FROM_DEVICE);
879+ if (dma_mapping_error(NULL, desc->sdp)) {
880+ return -EIO;
881+ }
882+ rx_ring->buff_tab[i] = skb;
883+ rx_ring->phys_tab[i] = desc->sdp;
884+ desc->cown = 0;
885+ }
886+ __raw_writel(rx_ring->phys_addr, &sw->regs->fs_desc_ptr0);
887+ __raw_writel(rx_ring->phys_addr, &sw->regs->fs_desc_base_addr0);
888+
889+ if (!(tx_dma_pool = dma_pool_create(DRV_NAME, NULL,
890+ TX_POOL_ALLOC_SIZE, 32, 0)))
891+ return -ENOMEM;
892+
893+ if (!(tx_ring->desc = dma_pool_alloc(tx_dma_pool, GFP_KERNEL,
894+ &tx_ring->phys_addr)))
895+ return -ENOMEM;
896+ memset(tx_ring->desc, 0, TX_POOL_ALLOC_SIZE);
897+
898+ /* Setup TX buffers */
899+ for (i = 0; i < TX_DESCS; i++) {
900+ struct tx_desc *desc = &(tx_ring)->desc[i];
901+ tx_ring->buff_tab[i] = 0;
902+
903+ if (i == (TX_DESCS - 1))
904+ desc->eor = 1;
905+ desc->cown = 1;
906+ }
907+ __raw_writel(tx_ring->phys_addr, &sw->regs->ts_desc_ptr0);
908+ __raw_writel(tx_ring->phys_addr, &sw->regs->ts_desc_base_addr0);
909+
910+ return 0;
911+}
912+
913+static void destroy_rings(struct sw *sw)
914+{
915+ int i;
916+ if (sw->rx_ring->desc) {
917+ for (i = 0; i < RX_DESCS; i++) {
918+ struct _rx_ring *rx_ring = sw->rx_ring;
919+ struct rx_desc *desc = &(rx_ring)->desc[i];
920+ struct sk_buff *skb = sw->rx_ring->buff_tab[i];
921+ if (skb) {
922+ dma_unmap_single(NULL,
923+ desc->sdp,
924+ CNS3XXX_MAX_MTU, DMA_FROM_DEVICE);
925+ dev_kfree_skb(skb);
926+ }
927+ }
928+ dma_pool_free(rx_dma_pool, sw->rx_ring->desc, sw->rx_ring->phys_addr);
929+ dma_pool_destroy(rx_dma_pool);
930+ rx_dma_pool = 0;
931+ sw->rx_ring->desc = 0;
932+ }
933+ if (sw->tx_ring->desc) {
934+ for (i = 0; i < TX_DESCS; i++) {
935+ struct _tx_ring *tx_ring = sw->tx_ring;
936+ struct tx_desc *desc = &(tx_ring)->desc[i];
937+ struct sk_buff *skb = sw->tx_ring->buff_tab[i];
938+ if (skb) {
939+ dma_unmap_single(NULL, desc->sdp,
940+ skb->len, DMA_TO_DEVICE);
941+ dev_kfree_skb(skb);
942+ }
943+ }
944+ dma_pool_free(tx_dma_pool, sw->tx_ring->desc, sw->tx_ring->phys_addr);
945+ dma_pool_destroy(tx_dma_pool);
946+ tx_dma_pool = 0;
947+ sw->tx_ring->desc = 0;
948+ }
949+}
950+
951+static int eth_open(struct net_device *dev)
952+{
953+ struct port *port = netdev_priv(dev);
954+ struct sw *sw = port->sw;
955+ u32 temp;
956+
957+ port->speed = 0; /* force "link up" message */
958+ phy_start(port->phydev);
959+
960+ netif_start_queue(dev);
961+
962+ if (!ports_open) {
963+ request_irq(IRQ_CNS3XXX_SW_R0RXC, eth_rx_irq, IRQF_SHARED, "gig_switch", napi_dev);
964+ request_irq(IRQ_CNS3XXX_SW_STATUS, eth_stat_irq, IRQF_SHARED, "gig_stat", napi_dev);
965+ napi_enable(&sw->napi);
966+ netif_start_queue(napi_dev);
967+
968+ __raw_writel(~(MAC0_STATUS_CHANGE | MAC1_STATUS_CHANGE | MAC2_STATUS_CHANGE |
969+ MAC0_RX_ERROR | MAC1_RX_ERROR | MAC2_RX_ERROR), &sw->regs->intr_mask);
970+
971+ temp = __raw_readl(&sw->regs->mac_cfg[2]);
972+ temp &= ~(PORT_DISABLE);
973+ __raw_writel(temp, &sw->regs->mac_cfg[2]);
974+
975+ temp = __raw_readl(&sw->regs->dma_auto_poll_cfg);
976+ temp &= ~(TS_SUSPEND | FS_SUSPEND);
977+ __raw_writel(temp, &sw->regs->dma_auto_poll_cfg);
978+
979+ enable_rx_dma(sw);
980+ }
981+ temp = __raw_readl(&sw->regs->mac_cfg[port->id]);
982+ temp &= ~(PORT_DISABLE);
983+ __raw_writel(temp, &sw->regs->mac_cfg[port->id]);
984+
985+ ports_open++;
986+ netif_carrier_on(dev);
987+
988+ return 0;
989+}
990+
991+static int eth_close(struct net_device *dev)
992+{
993+ struct port *port = netdev_priv(dev);
994+ struct sw *sw = port->sw;
995+ u32 temp;
996+
997+ ports_open--;
998+
999+ temp = __raw_readl(&sw->regs->mac_cfg[port->id]);
1000+ temp |= (PORT_DISABLE);
1001+ __raw_writel(temp, &sw->regs->mac_cfg[port->id]);
1002+
1003+ netif_stop_queue(dev);
1004+
1005+ phy_stop(port->phydev);
1006+
1007+ if (!ports_open) {
1008+ disable_irq(IRQ_CNS3XXX_SW_R0RXC);
1009+ free_irq(IRQ_CNS3XXX_SW_R0RXC, napi_dev);
1010+ disable_irq(IRQ_CNS3XXX_SW_STATUS);
1011+ free_irq(IRQ_CNS3XXX_SW_STATUS, napi_dev);
1012+ napi_disable(&sw->napi);
1013+ netif_stop_queue(napi_dev);
1014+ temp = __raw_readl(&sw->regs->mac_cfg[2]);
1015+ temp |= (PORT_DISABLE);
1016+ __raw_writel(temp, &sw->regs->mac_cfg[2]);
1017+
1018+ __raw_writel(TS_SUSPEND | FS_SUSPEND,
1019+ &sw->regs->dma_auto_poll_cfg);
1020+ }
1021+
1022+ netif_carrier_off(dev);
1023+ return 0;
1024+}
1025+
1026+static void eth_rx_mode(struct net_device *dev)
1027+{
1028+ struct port *port = netdev_priv(dev);
1029+ struct sw *sw = port->sw;
1030+ u32 temp;
1031+
1032+ temp = __raw_readl(&sw->regs->mac_glob_cfg);
1033+
1034+ if (dev->flags & IFF_PROMISC) {
1035+ if (port->id == 3)
1036+ temp |= ((1 << 2) << PROMISC_OFFSET);
1037+ else
1038+ temp |= ((1 << port->id) << PROMISC_OFFSET);
1039+ } else {
1040+ if (port->id == 3)
1041+ temp &= ~((1 << 2) << PROMISC_OFFSET);
1042+ else
1043+ temp &= ~((1 << port->id) << PROMISC_OFFSET);
1044+ }
1045+ __raw_writel(temp, &sw->regs->mac_glob_cfg);
1046+}
1047+
1048+static int eth_set_mac(struct net_device *netdev, void *p)
1049+{
1050+ struct port *port = netdev_priv(netdev);
1051+ struct sw *sw = port->sw;
1052+ struct sockaddr *addr = p;
1053+ u32 cycles = 0;
1054+
1055+ if (!is_valid_ether_addr(addr->sa_data))
1056+ return -EADDRNOTAVAIL;
1057+
1058+ /* Invalidate old ARL Entry */
1059+ if (port->id == 3)
1060+ __raw_writel((port->id << 16) | (0x4 << 9), &sw->regs->arl_ctrl[0]);
1061+ else
1062+ __raw_writel(((port->id + 1) << 16) | (0x4 << 9), &sw->regs->arl_ctrl[0]);
1063+ __raw_writel( ((netdev->dev_addr[0] << 24) | (netdev->dev_addr[1] << 16) |
1064+ (netdev->dev_addr[2] << 8) | (netdev->dev_addr[3])),
1065+ &sw->regs->arl_ctrl[1]);
1066+
1067+ __raw_writel( ((netdev->dev_addr[4] << 24) | (netdev->dev_addr[5] << 16) |
1068+ (1 << 1)),
1069+ &sw->regs->arl_ctrl[2]);
1070+ __raw_writel((1 << 19), &sw->regs->arl_vlan_cmd);
1071+
1072+ while (((__raw_readl(&sw->regs->arl_vlan_cmd) & (1 << 21)) == 0)
1073+ && cycles < 5000) {
1074+ udelay(1);
1075+ cycles++;
1076+ }
1077+
1078+ cycles = 0;
1079+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
1080+
1081+ if (port->id == 3)
1082+ __raw_writel((port->id << 16) | (0x4 << 9), &sw->regs->arl_ctrl[0]);
1083+ else
1084+ __raw_writel(((port->id + 1) << 16) | (0x4 << 9), &sw->regs->arl_ctrl[0]);
1085+ __raw_writel( ((addr->sa_data[0] << 24) | (addr->sa_data[1] << 16) |
1086+ (addr->sa_data[2] << 8) | (addr->sa_data[3])),
1087+ &sw->regs->arl_ctrl[1]);
1088+
1089+ __raw_writel( ((addr->sa_data[4] << 24) | (addr->sa_data[5] << 16) |
1090+ (7 << 4) | (1 << 1)), &sw->regs->arl_ctrl[2]);
1091+ __raw_writel((1 << 19), &sw->regs->arl_vlan_cmd);
1092+
1093+ while (((__raw_readl(&sw->regs->arl_vlan_cmd) & (1 << 21)) == 0)
1094+ && cycles < 5000) {
1095+ udelay(1);
1096+ cycles++;
1097+ }
1098+ return 0;
1099+}
1100+
1101+static const struct net_device_ops cns3xxx_netdev_ops = {
1102+ .ndo_open = eth_open,
1103+ .ndo_stop = eth_close,
1104+ .ndo_start_xmit = eth_xmit,
1105+ .ndo_set_rx_mode = eth_rx_mode,
1106+ .ndo_do_ioctl = eth_ioctl,
1107+ .ndo_change_mtu = eth_change_mtu,
1108+ .ndo_set_mac_address = eth_set_mac,
1109+ .ndo_validate_addr = eth_validate_addr,
1110+};
1111+
1112+static int __devinit eth_init_one(struct platform_device *pdev)
1113+{
1114+ int i;
1115+ struct port *port;
1116+ struct sw *sw;
1117+ struct net_device *dev;
1118+ struct cns3xxx_plat_info *plat = pdev->dev.platform_data;
1119+ u32 regs_phys;
1120+ char phy_id[MII_BUS_ID_SIZE + 3];
1121+ int err;
1122+ u32 temp;
1123+
1124+ if (!(napi_dev = alloc_etherdev(sizeof(struct sw))))
1125+ return -ENOMEM;
1126+ strcpy(napi_dev->name, "switch%d");
1127+ napi_dev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
1128+
1129+ SET_NETDEV_DEV(napi_dev, &pdev->dev);
1130+ sw = netdev_priv(napi_dev);
1131+ memset(sw, 0, sizeof(struct sw));
1132+ sw->regs = (struct switch_regs __iomem *)CNS3XXX_SWITCH_BASE_VIRT;
1133+ regs_phys = CNS3XXX_SWITCH_BASE;
1134+ sw->mem_res = request_mem_region(regs_phys, REGS_SIZE, napi_dev->name);
1135+ if (!sw->mem_res) {
1136+ err = -EBUSY;
1137+ goto err_free;
1138+ }
1139+
1140+ for (i = 0; i < 4; i++) {
1141+ temp = __raw_readl(&sw->regs->mac_cfg[i]);
1142+ temp |= (PORT_DISABLE);
1143+ __raw_writel(temp, &sw->regs->mac_cfg[i]);
1144+ }
1145+
1146+ temp = PORT_DISABLE;
1147+ __raw_writel(temp, &sw->regs->mac_cfg[2]);
1148+
1149+ temp = __raw_readl(&sw->regs->vlan_cfg);
1150+ temp |= NIC_MODE | VLAN_UNAWARE;
1151+ __raw_writel(temp, &sw->regs->vlan_cfg);
1152+
1153+ __raw_writel(UNKNOWN_VLAN_TO_CPU |
1154+ CRC_STRIPPING, &sw->regs->mac_glob_cfg);
1155+
1156+ if (!(sw->rx_ring = kmalloc(sizeof(struct _rx_ring), GFP_KERNEL))) {
1157+ err = -ENOMEM;
1158+ goto err_free;
1159+ }
1160+ memset(sw->rx_ring, 0, sizeof(struct _rx_ring));
1161+
1162+ if (!(sw->tx_ring = kmalloc(sizeof(struct _tx_ring), GFP_KERNEL))) {
1163+ err = -ENOMEM;
1164+ goto err_free_rx;
1165+ }
1166+ memset(sw->tx_ring, 0, sizeof(struct _tx_ring));
1167+
1168+ if ((err = init_rings(sw)) != 0) {
1169+ destroy_rings(sw);
1170+ err = -ENOMEM;
1171+ goto err_free_rings;
1172+ }
1173+ platform_set_drvdata(pdev, napi_dev);
1174+
1175+ netif_napi_add(napi_dev, &sw->napi, eth_poll, NAPI_WEIGHT);
1176+
1177+ for (i = 0; i < 3; i++) {
1178+ if (!(plat->ports & (1 << i))) {
1179+ continue;
1180+ }
1181+
1182+ if (!(dev = alloc_etherdev(sizeof(struct port)))) {
1183+ goto free_ports;
1184+ }
1185+
1186+ port = netdev_priv(dev);
1187+ port->netdev = dev;
1188+ if (i == 2)
1189+ port->id = 3;
1190+ else
1191+ port->id = i;
1192+ port->sw = sw;
1193+
1194+ temp = __raw_readl(&sw->regs->mac_cfg[port->id]);
1195+ temp |= (PORT_DISABLE | PORT_BLOCK_STATE | PORT_LEARN_DIS);
1196+ __raw_writel(temp, &sw->regs->mac_cfg[port->id]);
1197+
1198+ dev->netdev_ops = &cns3xxx_netdev_ops;
1199+ dev->ethtool_ops = &cns3xxx_ethtool_ops;
1200+ dev->tx_queue_len = 1000;
1201+ dev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
1202+
1203+ switch_port_tab[port->id] = port;
1204+ memcpy(dev->dev_addr, &plat->hwaddr[i], ETH_ALEN);
1205+
1206+ snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy[i]);
1207+ port->phydev = phy_connect(dev, phy_id, &cns3xxx_adjust_link, 0,
1208+ PHY_INTERFACE_MODE_RGMII);
1209+ if ((err = IS_ERR(port->phydev))) {
1210+ switch_port_tab[port->id] = 0;
1211+ free_netdev(dev);
1212+ goto free_ports;
1213+ }
1214+
1215+ port->phydev->irq = PHY_IGNORE_INTERRUPT;
1216+
1217+ if ((err = register_netdev(dev))) {
1218+ phy_disconnect(port->phydev);
1219+ switch_port_tab[port->id] = 0;
1220+ free_netdev(dev);
1221+ goto free_ports;
1222+ }
1223+
1224+ printk(KERN_INFO "%s: RGMII PHY %i on cns3xxx Switch\n", dev->name, plat->phy[i]);
1225+ netif_carrier_off(dev);
1226+ dev = 0;
1227+ }
1228+
1229+ return 0;
1230+
1231+free_ports:
1232+ err = -ENOMEM;
1233+ for (--i; i >= 0; i--) {
1234+ if (switch_port_tab[i]) {
1235+ port = switch_port_tab[i];
1236+ dev = port->netdev;
1237+ unregister_netdev(dev);
1238+ phy_disconnect(port->phydev);
1239+ switch_port_tab[i] = 0;
1240+ free_netdev(dev);
1241+ }
1242+ }
1243+err_free_rings:
1244+ kfree(sw->tx_ring);
1245+err_free_rx:
1246+ kfree(sw->rx_ring);
1247+err_free:
1248+ free_netdev(napi_dev);
1249+ return err;
1250+}
1251+
1252+static int __devexit eth_remove_one(struct platform_device *pdev)
1253+{
1254+ struct net_device *dev = platform_get_drvdata(pdev);
1255+ struct sw *sw = netdev_priv(dev);
1256+ int i;
1257+ destroy_rings(sw);
1258+
1259+ for (i = 3; i >= 0; i--) {
1260+ if (switch_port_tab[i]) {
1261+ struct port *port = switch_port_tab[i];
1262+ struct net_device *dev = port->netdev;
1263+ unregister_netdev(dev);
1264+ phy_disconnect(port->phydev);
1265+ switch_port_tab[i] = 0;
1266+ free_netdev(dev);
1267+ }
1268+ }
1269+
1270+ release_resource(sw->mem_res);
1271+ free_netdev(napi_dev);
1272+ return 0;
1273+}
1274+
1275+static struct platform_driver cns3xxx_eth_driver = {
1276+ .driver.name = DRV_NAME,
1277+ .probe = eth_init_one,
1278+ .remove = eth_remove_one,
1279+};
1280+
1281+static int __init eth_init_module(void)
1282+{
1283+ int err;
1284+ if ((err = cns3xxx_mdio_register()))
1285+ return err;
1286+ return platform_driver_register(&cns3xxx_eth_driver);
1287+}
1288+
1289+static void __exit eth_cleanup_module(void)
1290+{
1291+ platform_driver_unregister(&cns3xxx_eth_driver);
1292+ cns3xxx_mdio_remove();
1293+}
1294+
1295+module_init(eth_init_module);
1296+module_exit(eth_cleanup_module);
1297+
1298+MODULE_AUTHOR("Chris Lang");
1299+MODULE_DESCRIPTION("Cavium CNS3xxx Ethernet driver");
1300+MODULE_LICENSE("GPL v2");
1301+MODULE_ALIAS("platform:cns3xxx_eth");
1302--- /dev/null
1303+++ b/arch/arm/mach-cns3xxx/include/mach/platform.h
1304@@ -0,0 +1,26 @@
1305+/*
1306+ * arch/arm/mach-cns3xxx/include/mach/platform.h
1307+ *
1308+ * Copyright 2011 Gateworks Corporation
1309+ * Chris Lang <clang@gateworks.com
1310+ *
1311+ * This file is free software; you can redistribute it and/or modify
1312+ * it under the terms of the GNU General Public License, Version 2, as
1313+ * published by the Free Software Foundation.
1314+ *
1315+ */
1316+
1317+#ifndef __ASM_ARCH_PLATFORM_H
1318+#define __ASM_ARCH_PLATFORM_H
1319+
1320+#ifndef __ASSEMBLY__
1321+
1322+/* Information about built-in Ethernet MAC interfaces */
1323+struct cns3xxx_plat_info {
1324+ u8 ports; /* Bitmap of enabled Ports */
1325+ u8 hwaddr[4][6];
1326+ u32 phy[3];
1327+};
1328+
1329+#endif /* __ASM_ARCH_PLATFORM_H */
1330+#endif
1331--- a/drivers/net/ethernet/Kconfig
1332+++ b/drivers/net/ethernet/Kconfig
1333@@ -32,6 +32,7 @@ source "drivers/net/ethernet/calxeda/Kco
1334 source "drivers/net/ethernet/chelsio/Kconfig"
1335 source "drivers/net/ethernet/cirrus/Kconfig"
1336 source "drivers/net/ethernet/cisco/Kconfig"
1337+source "drivers/net/ethernet/cavium/Kconfig"
1338 source "drivers/net/ethernet/davicom/Kconfig"
1339 
1340 config DNET
1341--- a/drivers/net/ethernet/Makefile
1342+++ b/drivers/net/ethernet/Makefile
1343@@ -15,6 +15,7 @@ obj-$(CONFIG_NET_BFIN) += adi/
1344 obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/
1345 obj-$(CONFIG_NET_VENDOR_BROCADE) += brocade/
1346 obj-$(CONFIG_NET_CALXEDA_XGMAC) += calxeda/
1347+obj-$(CONFIG_NET_VENDOR_CAVIUM) += cavium/
1348 obj-$(CONFIG_NET_VENDOR_CHELSIO) += chelsio/
1349 obj-$(CONFIG_NET_VENDOR_CIRRUS) += cirrus/
1350 obj-$(CONFIG_NET_VENDOR_CISCO) += cisco/
1351--- /dev/null
1352+++ b/drivers/net/ethernet/cavium/Kconfig
1353@@ -0,0 +1,24 @@
1354+config NET_VENDOR_CAVIUM
1355+ bool "Cavium devices"
1356+ default y
1357+ depends on ARCH_CNS3XXX
1358+ ---help---
1359+ If you have a network (Ethernet) chipset belonging to this class,
1360+ say Y.
1361+
1362+ Note that the answer to this question does not directly affect
1363+ the kernel: saying N will just case the configurator to skip all
1364+ the questions regarding AMD chipsets. If you say Y, you will be asked
1365+ for your specific chipset/driver in the following questions.
1366+
1367+if NET_VENDOR_CAVIUM
1368+
1369+config CNS3XXX_ETH
1370+ tristate "Cavium CNS3xxx Ethernet support"
1371+ depends on ARCH_CNS3XXX
1372+ select PHYLIB
1373+ help
1374+ Say Y here if you want to use built-in Ethernet ports
1375+ on CNS3XXX processor.
1376+
1377+endif
1378--- /dev/null
1379+++ b/drivers/net/ethernet/cavium/Makefile
1380@@ -0,0 +1,5 @@
1381+#
1382+# Makefile for the Cavium ethernet device drivers.
1383+#
1384+
1385+obj-$(CONFIG_CNS3XXX_ETH) += cns3xxx_eth.o
1386

Archive Download this file



interactive