1 From 435de86088af82496bcba69165cd7422bb4622ec Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Fri, 6 May 2011 00:10:01 +0200
4 Subject: [PATCH 11/13] MIPS: Lantiq: Add ethernet driver
6 This patch adds the driver for the ETOP Packet Processing Engine (PPE32)
7 found inside the XWAY family of Lantiq MIPS SoCs. This driver makes 100MBit
8 ethernet work. Support for all 8 dma channels, gbit and the embedded switch
9 found on the ar9/vr9 still needs to be implemented.
11 Signed-off-by: John Crispin <blogic@openwrt.org>
12 Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
13 Cc: linux-mips@linux-mips.org
14 Cc: netdev@vger.kernel.org
15 Patchwork: https://patchwork.linux-mips.org/patch/2357/
16 Acked-by: David S. Miller <davem@davemloft.net>
17 Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
19 .../mips/include/asm/mach-lantiq/lantiq_platform.h | 7 +
20 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 4 +-
21 arch/mips/lantiq/xway/devices.c | 23 +
22 arch/mips/lantiq/xway/devices.h | 1 +
23 drivers/net/Kconfig | 7 +
24 drivers/net/Makefile | 1 +
25 drivers/net/lantiq_etop.c | 805 ++++++++++++++++++++
26 7 files changed, 846 insertions(+), 2 deletions(-)
27 create mode 100644 drivers/net/lantiq_etop.c
29 --- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
30 +++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
32 #define _LANTIQ_PLATFORM_H__
34 #include <linux/mtd/partitions.h>
35 +#include <linux/socket.h>
37 /* struct used to pass info to the pci core */
43 +/* struct used to pass info to network drivers */
44 +struct ltq_eth_data {
45 + struct sockaddr mac;
50 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
51 +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
53 #define PMU_SWITCH 0x10000000
56 -#define LTQ_PPE32_BASE_ADDR 0xBE180000
57 -#define LTQ_PPE32_SIZE 0x40000
58 +#define LTQ_ETOP_BASE_ADDR 0x1E180000
59 +#define LTQ_ETOP_SIZE 0x40000
62 #define LTQ_DMA_BASE_ADDR 0x1E104100
63 --- a/arch/mips/lantiq/xway/devices.c
64 +++ b/arch/mips/lantiq/xway/devices.c
66 platform_device_register_simple("ltq_asc", 0,
67 ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources));
71 +static struct resource ltq_etop_resources = {
73 + .start = LTQ_ETOP_BASE_ADDR,
74 + .end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1,
75 + .flags = IORESOURCE_MEM,
78 +static struct platform_device ltq_etop = {
80 + .resource = <q_etop_resources,
85 +ltq_register_etop(struct ltq_eth_data *eth)
88 + ltq_etop.dev.platform_data = eth;
89 + platform_device_register(<q_etop);
92 --- a/arch/mips/lantiq/xway/devices.h
93 +++ b/arch/mips/lantiq/xway/devices.h
95 extern void ltq_register_gpio(void);
96 extern void ltq_register_gpio_stp(void);
97 extern void ltq_register_ase_asc(void);
98 +extern void ltq_register_etop(struct ltq_eth_data *eth);
101 --- a/drivers/net/Kconfig
102 +++ b/drivers/net/Kconfig
103 @@ -1951,6 +1951,13 @@
104 This driver supports the ethernet MACs in the Broadcom 63xx
105 MIPS chipset family (BCM63XX).
108 + tristate "Lantiq SoC ETOP driver"
109 + depends on SOC_TYPE_XWAY
111 + Support for the MII0 inside the Lantiq SoC
114 source "drivers/net/fs_enet/Kconfig"
117 --- a/drivers/net/Makefile
118 +++ b/drivers/net/Makefile
120 obj-$(CONFIG_MLX4_CORE) += mlx4/
121 obj-$(CONFIG_ENC28J60) += enc28j60.o
122 obj-$(CONFIG_ETHOC) += ethoc.o
123 +obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
125 obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
128 +++ b/drivers/net/lantiq_etop.c
131 + * This program is free software; you can redistribute it and/or modify it
132 + * under the terms of the GNU General Public License version 2 as published
133 + * by the Free Software Foundation.
135 + * This program is distributed in the hope that it will be useful,
136 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
137 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
138 + * GNU General Public License for more details.
140 + * You should have received a copy of the GNU General Public License
141 + * along with this program; if not, write to the Free Software
142 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
144 + * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
147 +#include <linux/kernel.h>
148 +#include <linux/slab.h>
149 +#include <linux/errno.h>
150 +#include <linux/types.h>
151 +#include <linux/interrupt.h>
152 +#include <linux/uaccess.h>
153 +#include <linux/in.h>
154 +#include <linux/netdevice.h>
155 +#include <linux/etherdevice.h>
156 +#include <linux/phy.h>
157 +#include <linux/ip.h>
158 +#include <linux/tcp.h>
159 +#include <linux/skbuff.h>
160 +#include <linux/mm.h>
161 +#include <linux/platform_device.h>
162 +#include <linux/ethtool.h>
163 +#include <linux/init.h>
164 +#include <linux/delay.h>
165 +#include <linux/io.h>
167 +#include <asm/checksum.h>
169 +#include <lantiq_soc.h>
170 +#include <xway_dma.h>
171 +#include <lantiq_platform.h>
173 +#define LTQ_ETOP_MDIO 0x11804
174 +#define MDIO_REQUEST 0x80000000
175 +#define MDIO_READ 0x40000000
176 +#define MDIO_ADDR_MASK 0x1f
177 +#define MDIO_ADDR_OFFSET 0x15
178 +#define MDIO_REG_MASK 0x1f
179 +#define MDIO_REG_OFFSET 0x10
180 +#define MDIO_VAL_MASK 0xffff
182 +#define PPE32_CGEN 0x800
183 +#define LTQ_PPE32_ENET_MAC_CFG 0x1840
185 +#define LTQ_ETOP_ENETS0 0x11850
186 +#define LTQ_ETOP_MAC_DA0 0x1186C
187 +#define LTQ_ETOP_MAC_DA1 0x11870
188 +#define LTQ_ETOP_CFG 0x16020
189 +#define LTQ_ETOP_IGPLEN 0x16080
191 +#define MAX_DMA_CHAN 0x8
192 +#define MAX_DMA_CRC_LEN 0x4
193 +#define MAX_DMA_DATA_LEN 0x600
195 +#define ETOP_FTCU BIT(28)
196 +#define ETOP_MII_MASK 0xf
197 +#define ETOP_MII_NORMAL 0xd
198 +#define ETOP_MII_REVERSE 0xe
199 +#define ETOP_PLEN_UNDER 0x40
200 +#define ETOP_CGEN 0x800
202 +/* use 2 static channels for TX/RX */
203 +#define LTQ_ETOP_TX_CHANNEL 1
204 +#define LTQ_ETOP_RX_CHANNEL 6
205 +#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
206 +#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
208 +#define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x))
209 +#define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y))
210 +#define ltq_etop_w32_mask(x, y, z) \
211 + ltq_w32_mask(x, y, ltq_etop_membase + (z))
213 +#define DRV_VERSION "1.0"
216 +#define netdev_err(a, b, ...) printk(b, ##__VA_ARGS__)
220 +#define pr_warn pr_warning
223 +static void __iomem *ltq_etop_membase;
225 +struct ltq_etop_chan {
228 + struct net_device *netdev;
229 + struct napi_struct napi;
230 + struct ltq_dma_channel dma;
231 + struct sk_buff *skb[LTQ_DESC_NUM];
234 +struct ltq_etop_priv {
235 + struct net_device *netdev;
236 + struct ltq_eth_data *pldata;
237 + struct resource *res;
239 + struct mii_bus *mii_bus;
240 + struct phy_device *phydev;
242 + struct ltq_etop_chan ch[MAX_DMA_CHAN];
243 + int tx_free[MAX_DMA_CHAN >> 1];
249 +ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
251 + ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
252 + if (!ch->skb[ch->dma.desc])
254 + ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL,
255 + ch->skb[ch->dma.desc]->data, MAX_DMA_DATA_LEN,
257 + ch->dma.desc_base[ch->dma.desc].addr =
258 + CPHYSADDR(ch->skb[ch->dma.desc]->data);
259 + ch->dma.desc_base[ch->dma.desc].ctl =
260 + LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
262 + skb_reserve(ch->skb[ch->dma.desc], NET_IP_ALIGN);
267 +ltq_etop_hw_receive(struct ltq_etop_chan *ch)
269 + struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
270 + struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
271 + struct sk_buff *skb = ch->skb[ch->dma.desc];
272 + int len = (desc->ctl & LTQ_DMA_SIZE_MASK) - MAX_DMA_CRC_LEN;
273 + unsigned long flags;
275 + spin_lock_irqsave(&priv->lock, flags);
276 + if (ltq_etop_alloc_skb(ch)) {
277 + netdev_err(ch->netdev,
278 + "failed to allocate new rx buffer, stopping DMA\n");
279 + ltq_dma_close(&ch->dma);
282 + ch->dma.desc %= LTQ_DESC_NUM;
283 + spin_unlock_irqrestore(&priv->lock, flags);
286 + skb->dev = ch->netdev;
287 + skb->protocol = eth_type_trans(skb, ch->netdev);
288 + netif_receive_skb(skb);
292 +ltq_etop_poll_rx(struct napi_struct *napi, int budget)
294 + struct ltq_etop_chan *ch = container_of(napi,
295 + struct ltq_etop_chan, napi);
299 + while ((rx < budget) && !complete) {
300 + struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
302 + if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
303 + ltq_etop_hw_receive(ch);
309 + if (complete || !rx) {
310 + napi_complete(&ch->napi);
311 + ltq_dma_ack_irq(&ch->dma);
317 +ltq_etop_poll_tx(struct napi_struct *napi, int budget)
319 + struct ltq_etop_chan *ch =
320 + container_of(napi, struct ltq_etop_chan, napi);
321 + struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
322 + struct netdev_queue *txq =
323 + netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
324 + unsigned long flags;
326 + spin_lock_irqsave(&priv->lock, flags);
327 + while ((ch->dma.desc_base[ch->tx_free].ctl &
328 + (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
329 + dev_kfree_skb_any(ch->skb[ch->tx_free]);
330 + ch->skb[ch->tx_free] = NULL;
331 + memset(&ch->dma.desc_base[ch->tx_free], 0,
332 + sizeof(struct ltq_dma_desc));
334 + ch->tx_free %= LTQ_DESC_NUM;
336 + spin_unlock_irqrestore(&priv->lock, flags);
338 + if (netif_tx_queue_stopped(txq))
339 + netif_tx_start_queue(txq);
340 + napi_complete(&ch->napi);
341 + ltq_dma_ack_irq(&ch->dma);
346 +ltq_etop_dma_irq(int irq, void *_priv)
348 + struct ltq_etop_priv *priv = _priv;
349 + int ch = irq - LTQ_DMA_CH0_INT;
351 + napi_schedule(&priv->ch[ch].napi);
352 + return IRQ_HANDLED;
356 +ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch)
358 + struct ltq_etop_priv *priv = netdev_priv(dev);
360 + ltq_dma_free(&ch->dma);
362 + free_irq(ch->dma.irq, priv);
363 + if (IS_RX(ch->idx)) {
365 + for (desc = 0; desc < LTQ_DESC_NUM; desc++)
366 + dev_kfree_skb_any(ch->skb[ch->dma.desc]);
371 +ltq_etop_hw_exit(struct net_device *dev)
373 + struct ltq_etop_priv *priv = netdev_priv(dev);
376 + ltq_pmu_disable(PMU_PPE);
377 + for (i = 0; i < MAX_DMA_CHAN; i++)
378 + if (IS_TX(i) || IS_RX(i))
379 + ltq_etop_free_channel(dev, &priv->ch[i]);
383 +ltq_etop_hw_init(struct net_device *dev)
385 + struct ltq_etop_priv *priv = netdev_priv(dev);
388 + ltq_pmu_enable(PMU_PPE);
390 + switch (priv->pldata->mii_mode) {
391 + case PHY_INTERFACE_MODE_RMII:
392 + ltq_etop_w32_mask(ETOP_MII_MASK,
393 + ETOP_MII_REVERSE, LTQ_ETOP_CFG);
396 + case PHY_INTERFACE_MODE_MII:
397 + ltq_etop_w32_mask(ETOP_MII_MASK,
398 + ETOP_MII_NORMAL, LTQ_ETOP_CFG);
402 + netdev_err(dev, "unknown mii mode %d\n",
403 + priv->pldata->mii_mode);
407 + /* enable crc generation */
408 + ltq_etop_w32(PPE32_CGEN, LTQ_PPE32_ENET_MAC_CFG);
410 + ltq_dma_init_port(DMA_PORT_ETOP);
412 + for (i = 0; i < MAX_DMA_CHAN; i++) {
413 + int irq = LTQ_DMA_CH0_INT + i;
414 + struct ltq_etop_chan *ch = &priv->ch[i];
416 + ch->idx = ch->dma.nr = i;
419 + ltq_dma_alloc_tx(&ch->dma);
420 + request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
422 + } else if (IS_RX(i)) {
423 + ltq_dma_alloc_rx(&ch->dma);
424 + for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
426 + if (ltq_etop_alloc_skb(ch))
429 + request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
438 +ltq_etop_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
440 + strcpy(info->driver, "Lantiq ETOP");
441 + strcpy(info->bus_info, "internal");
442 + strcpy(info->version, DRV_VERSION);
446 +ltq_etop_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
448 + struct ltq_etop_priv *priv = netdev_priv(dev);
450 + return phy_ethtool_gset(priv->phydev, cmd);
454 +ltq_etop_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
456 + struct ltq_etop_priv *priv = netdev_priv(dev);
458 + return phy_ethtool_sset(priv->phydev, cmd);
462 +ltq_etop_nway_reset(struct net_device *dev)
464 + struct ltq_etop_priv *priv = netdev_priv(dev);
466 + return phy_start_aneg(priv->phydev);
469 +static const struct ethtool_ops ltq_etop_ethtool_ops = {
470 + .get_drvinfo = ltq_etop_get_drvinfo,
471 + .get_settings = ltq_etop_get_settings,
472 + .set_settings = ltq_etop_set_settings,
473 + .nway_reset = ltq_etop_nway_reset,
477 +ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
479 + u32 val = MDIO_REQUEST |
480 + ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
481 + ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
484 + while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
486 + ltq_etop_w32(val, LTQ_ETOP_MDIO);
491 +ltq_etop_mdio_rd(struct mii_bus *bus, int phy_addr, int phy_reg)
493 + u32 val = MDIO_REQUEST | MDIO_READ |
494 + ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
495 + ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
497 + while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
499 + ltq_etop_w32(val, LTQ_ETOP_MDIO);
500 + while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
502 + val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK;
507 +ltq_etop_mdio_link(struct net_device *dev)
509 + /* nothing to do */
513 +ltq_etop_mdio_probe(struct net_device *dev)
515 + struct ltq_etop_priv *priv = netdev_priv(dev);
516 + struct phy_device *phydev = NULL;
519 + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
520 + if (priv->mii_bus->phy_map[phy_addr]) {
521 + phydev = priv->mii_bus->phy_map[phy_addr];
527 + netdev_err(dev, "no PHY found\n");
531 + phydev = phy_connect(dev, dev_name(&phydev->dev), <q_etop_mdio_link,
532 + 0, priv->pldata->mii_mode);
534 + if (IS_ERR(phydev)) {
535 + netdev_err(dev, "Could not attach to PHY\n");
536 + return PTR_ERR(phydev);
539 + phydev->supported &= (SUPPORTED_10baseT_Half
540 + | SUPPORTED_10baseT_Full
541 + | SUPPORTED_100baseT_Half
542 + | SUPPORTED_100baseT_Full
543 + | SUPPORTED_Autoneg
547 + phydev->advertising = phydev->supported;
548 + priv->phydev = phydev;
549 + pr_info("%s: attached PHY [%s] (phy_addr=%s, irq=%d)\n",
550 + dev->name, phydev->drv->name,
551 + dev_name(&phydev->dev), phydev->irq);
557 +ltq_etop_mdio_init(struct net_device *dev)
559 + struct ltq_etop_priv *priv = netdev_priv(dev);
563 + priv->mii_bus = mdiobus_alloc();
564 + if (!priv->mii_bus) {
565 + netdev_err(dev, "failed to allocate mii bus\n");
570 + priv->mii_bus->priv = dev;
571 + priv->mii_bus->read = ltq_etop_mdio_rd;
572 + priv->mii_bus->write = ltq_etop_mdio_wr;
573 + priv->mii_bus->name = "ltq_mii";
574 + snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
575 + priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
576 + if (!priv->mii_bus->irq) {
578 + goto err_out_free_mdiobus;
581 + for (i = 0; i < PHY_MAX_ADDR; ++i)
582 + priv->mii_bus->irq[i] = PHY_POLL;
584 + if (mdiobus_register(priv->mii_bus)) {
586 + goto err_out_free_mdio_irq;
589 + if (ltq_etop_mdio_probe(dev)) {
591 + goto err_out_unregister_bus;
595 +err_out_unregister_bus:
596 + mdiobus_unregister(priv->mii_bus);
597 +err_out_free_mdio_irq:
598 + kfree(priv->mii_bus->irq);
599 +err_out_free_mdiobus:
600 + mdiobus_free(priv->mii_bus);
606 +ltq_etop_mdio_cleanup(struct net_device *dev)
608 + struct ltq_etop_priv *priv = netdev_priv(dev);
610 + phy_disconnect(priv->phydev);
611 + mdiobus_unregister(priv->mii_bus);
612 + kfree(priv->mii_bus->irq);
613 + mdiobus_free(priv->mii_bus);
617 +ltq_etop_open(struct net_device *dev)
619 + struct ltq_etop_priv *priv = netdev_priv(dev);
622 + for (i = 0; i < MAX_DMA_CHAN; i++) {
623 + struct ltq_etop_chan *ch = &priv->ch[i];
625 + if (!IS_TX(i) && (!IS_RX(i)))
627 + ltq_dma_open(&ch->dma);
628 + napi_enable(&ch->napi);
630 + phy_start(priv->phydev);
631 + netif_tx_start_all_queues(dev);
636 +ltq_etop_stop(struct net_device *dev)
638 + struct ltq_etop_priv *priv = netdev_priv(dev);
641 + netif_tx_stop_all_queues(dev);
642 + phy_stop(priv->phydev);
643 + for (i = 0; i < MAX_DMA_CHAN; i++) {
644 + struct ltq_etop_chan *ch = &priv->ch[i];
646 + if (!IS_RX(i) && !IS_TX(i))
648 + napi_disable(&ch->napi);
649 + ltq_dma_close(&ch->dma);
655 +ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
657 + int queue = skb_get_queue_mapping(skb);
658 + struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
659 + struct ltq_etop_priv *priv = netdev_priv(dev);
660 + struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
661 + struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
663 + unsigned long flags;
666 + len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
668 + if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
669 + dev_kfree_skb_any(skb);
670 + netdev_err(dev, "tx ring full\n");
671 + netif_tx_stop_queue(txq);
672 + return NETDEV_TX_BUSY;
675 + /* dma needs to start on a 16 byte aligned address */
676 + byte_offset = CPHYSADDR(skb->data) % 16;
677 + ch->skb[ch->dma.desc] = skb;
679 + dev->trans_start = jiffies;
681 + spin_lock_irqsave(&priv->lock, flags);
682 + desc->addr = ((unsigned int) dma_map_single(NULL, skb->data, len,
683 + DMA_TO_DEVICE)) - byte_offset;
685 + desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
686 + LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
688 + ch->dma.desc %= LTQ_DESC_NUM;
689 + spin_unlock_irqrestore(&priv->lock, flags);
691 + if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
692 + netif_tx_stop_queue(txq);
694 + return NETDEV_TX_OK;
698 +ltq_etop_change_mtu(struct net_device *dev, int new_mtu)
700 + int ret = eth_change_mtu(dev, new_mtu);
703 + struct ltq_etop_priv *priv = netdev_priv(dev);
704 + unsigned long flags;
706 + spin_lock_irqsave(&priv->lock, flags);
707 + ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu,
709 + spin_unlock_irqrestore(&priv->lock, flags);
715 +ltq_etop_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
717 + struct ltq_etop_priv *priv = netdev_priv(dev);
718 + struct mii_ioctl_data *data = if_mii(rq);
720 + /* TODO: mii-toll reports "No MII transceiver present!." ?!*/
721 + return phy_mii_ioctl(priv->phydev, data, cmd);
725 +ltq_etop_set_mac_address(struct net_device *dev, void *p)
727 + int ret = eth_mac_addr(dev, p);
730 + struct ltq_etop_priv *priv = netdev_priv(dev);
731 + unsigned long flags;
733 + /* store the mac for the unicast filter */
734 + spin_lock_irqsave(&priv->lock, flags);
735 + ltq_etop_w32(*((u32 *)dev->dev_addr), LTQ_ETOP_MAC_DA0);
736 + ltq_etop_w32(*((u16 *)&dev->dev_addr[4]) << 16,
738 + spin_unlock_irqrestore(&priv->lock, flags);
744 +ltq_etop_set_multicast_list(struct net_device *dev)
746 + struct ltq_etop_priv *priv = netdev_priv(dev);
747 + unsigned long flags;
749 + /* ensure that the unicast filter is not enabled in promiscious mode */
750 + spin_lock_irqsave(&priv->lock, flags);
751 + if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI))
752 + ltq_etop_w32_mask(ETOP_FTCU, 0, LTQ_ETOP_ENETS0);
754 + ltq_etop_w32_mask(0, ETOP_FTCU, LTQ_ETOP_ENETS0);
755 + spin_unlock_irqrestore(&priv->lock, flags);
759 +ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb)
761 + /* we are currently only using the first queue */
766 +ltq_etop_init(struct net_device *dev)
768 + struct ltq_etop_priv *priv = netdev_priv(dev);
769 + struct sockaddr mac;
773 + dev->watchdog_timeo = 10 * HZ;
774 + err = ltq_etop_hw_init(dev);
777 + ltq_etop_change_mtu(dev, 1500);
779 + memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
780 + if (!is_valid_ether_addr(mac.sa_data)) {
781 + pr_warn("etop: invalid MAC, using random\n");
782 + random_ether_addr(mac.sa_data);
785 + err = ltq_etop_set_mac_address(dev, &mac);
788 + ltq_etop_set_multicast_list(dev);
789 + err = ltq_etop_mdio_init(dev);
795 + unregister_netdev(dev);
798 + ltq_etop_hw_exit(dev);
803 +ltq_etop_tx_timeout(struct net_device *dev)
807 + ltq_etop_hw_exit(dev);
808 + err = ltq_etop_hw_init(dev);
811 + dev->trans_start = jiffies;
812 + netif_wake_queue(dev);
816 + ltq_etop_hw_exit(dev);
817 + netdev_err(dev, "failed to restart etop after TX timeout\n");
820 +static const struct net_device_ops ltq_eth_netdev_ops = {
821 + .ndo_open = ltq_etop_open,
822 + .ndo_stop = ltq_etop_stop,
823 + .ndo_start_xmit = ltq_etop_tx,
824 + .ndo_change_mtu = ltq_etop_change_mtu,
825 + .ndo_do_ioctl = ltq_etop_ioctl,
826 + .ndo_set_mac_address = ltq_etop_set_mac_address,
827 + .ndo_validate_addr = eth_validate_addr,
828 + .ndo_set_multicast_list = ltq_etop_set_multicast_list,
829 + .ndo_select_queue = ltq_etop_select_queue,
830 + .ndo_init = ltq_etop_init,
831 + .ndo_tx_timeout = ltq_etop_tx_timeout,
835 +ltq_etop_probe(struct platform_device *pdev)
837 + struct net_device *dev;
838 + struct ltq_etop_priv *priv;
839 + struct resource *res;
843 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
845 + dev_err(&pdev->dev, "failed to get etop resource\n");
850 + res = devm_request_mem_region(&pdev->dev, res->start,
851 + resource_size(res), dev_name(&pdev->dev));
853 + dev_err(&pdev->dev, "failed to request etop resource\n");
858 + ltq_etop_membase = devm_ioremap_nocache(&pdev->dev,
859 + res->start, resource_size(res));
860 + if (!ltq_etop_membase) {
861 + dev_err(&pdev->dev, "failed to remap etop engine %d\n",
867 + dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
868 + strcpy(dev->name, "eth%d");
869 + dev->netdev_ops = <q_eth_netdev_ops;
870 + dev->ethtool_ops = <q_etop_ethtool_ops;
871 + priv = netdev_priv(dev);
873 + priv->pldata = dev_get_platdata(&pdev->dev);
874 + priv->netdev = dev;
875 + spin_lock_init(&priv->lock);
877 + for (i = 0; i < MAX_DMA_CHAN; i++) {
879 + netif_napi_add(dev, &priv->ch[i].napi,
880 + ltq_etop_poll_tx, 8);
882 + netif_napi_add(dev, &priv->ch[i].napi,
883 + ltq_etop_poll_rx, 32);
884 + priv->ch[i].netdev = dev;
887 + err = register_netdev(dev);
891 + platform_set_drvdata(pdev, dev);
900 +static int __devexit
901 +ltq_etop_remove(struct platform_device *pdev)
903 + struct net_device *dev = platform_get_drvdata(pdev);
906 + netif_tx_stop_all_queues(dev);
907 + ltq_etop_hw_exit(dev);
908 + ltq_etop_mdio_cleanup(dev);
909 + unregister_netdev(dev);
914 +static struct platform_driver ltq_mii_driver = {
915 + .remove = __devexit_p(ltq_etop_remove),
917 + .name = "ltq_etop",
918 + .owner = THIS_MODULE,
925 + int ret = platform_driver_probe(<q_mii_driver, ltq_etop_probe);
928 + pr_err("ltq_etop: Error registering platfom driver!");
935 + platform_driver_unregister(<q_mii_driver);
938 +module_init(init_ltq_etop);
939 +module_exit(exit_ltq_etop);
941 +MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
942 +MODULE_DESCRIPTION("Lantiq SoC ETOP");
943 +MODULE_LICENSE("GPL");