--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
-@@ -107,7 +107,13 @@ config LANTIQ_ETOP
+@@ -106,7 +106,13 @@ config LANTIQ_ETOP
tristate "Lantiq SoC ETOP driver"
depends on SOC_TYPE_XWAY
---help---
source "drivers/net/ethernet/mediatek/Kconfig"
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
-@@ -50,6 +50,7 @@ obj-$(CONFIG_NET_VENDOR_XSCALE) += xscal
+@@ -49,6 +49,7 @@ obj-$(CONFIG_NET_VENDOR_XSCALE) += xscal
obj-$(CONFIG_JME) += jme.o
obj-$(CONFIG_KORINA) += korina.o
obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
+};
--- /dev/null
+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -0,0 +1,1887 @@
+@@ -0,0 +1,1924 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+struct xrx200_hw {
+ struct clk *clk;
+ struct mii_bus *mii_bus;
++ u8 phy_addr[XRX200_MAX_PORT];
+
+ struct xrx200_chan chan[XRX200_MAX_DMA];
+ u16 vlan_vid[XRX200_MAX_VLAN];
+ return 0;
+}
+
++static int xrx200sw_set_port_link(struct switch_dev *dev, int port,
++ struct switch_port_link *link)
++{
++ if (port >= XRX200_MAX_PORT)
++ return -EINVAL;
++
++ return switch_generic_set_link(dev, port, link);
++}
++
++static int xrx200_mdio_wr(struct mii_bus *bus, int addr, int reg, u16 val);
++static int xrx200_mdio_rd(struct mii_bus *bus, int addr, int reg);
++
++static int xrx200sw_phy_read16(struct switch_dev *dev, int addr, u8 reg, u16 *value)
++{
++ struct xrx200_hw *hw = container_of(dev, struct xrx200_hw, swdev);
++
++ *value = xrx200_mdio_rd(hw->mii_bus, hw->phy_addr[addr], reg);
++
++ return 0;
++}
++
++static int xrx200sw_phy_write16(struct switch_dev *dev, int addr, u8 reg, u16 value)
++{
++ struct xrx200_hw *hw = container_of(dev, struct xrx200_hw, swdev);
++
++ return xrx200_mdio_wr(hw->mii_bus, hw->phy_addr[addr], reg, value);
++}
++
+static int xrx200_set_port_attr(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
+{
+ if (val->port_vlan >= XRX200_MAX_PORT)
+ .get_port_pvid = xrx200sw_get_port_pvid,
+ .reset_switch = xrx200sw_reset_switch,
+ .get_port_link = xrx200sw_get_port_link,
++ .set_port_link = xrx200sw_set_port_link,
+// .get_port_stats = xrx200sw_get_port_stats, //TODO
++ .phy_read16 = xrx200sw_phy_read16,
++ .phy_write16 = xrx200sw_phy_write16,
+};
+
+static int xrx200sw_init(struct xrx200_hw *hw)
+ goto skip;
+
+ skb_reserve(ch->skb[ch->dma.desc], NET_SKB_PAD);
-+ ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL,
++ ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(ch->dma.dev,
+ ch->skb[ch->dma.desc]->data, XRX200_DMA_DATA_LEN,
+ DMA_FROM_DEVICE);
+ ch->dma.desc_base[ch->dma.desc].addr =
+
+ netif_trans_update(dev);
+
-+ desc->addr = ((unsigned int) dma_map_single(NULL, skb->data, len,
++ desc->addr = ((unsigned int) dma_map_single(ch->dma.dev, skb->data, len,
+ DMA_TO_DEVICE)) - byte_offset;
+ wmb();
+ desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
+ return IRQ_HANDLED;
+}
+
-+static int xrx200_dma_init(struct xrx200_hw *hw)
++static int xrx200_dma_init(struct device *dev, struct xrx200_hw *hw)
+{
+ int i, err = 0;
+
+ spin_lock_init(&ch->lock);
+
+ ch->idx = ch->dma.nr = i;
++ ch->dma.dev = dev;
+
+ if (i == XRX200_DMA_TX) {
+ ltq_dma_alloc_tx(&ch->dma);
+{
+ struct net_device *netdev = phydev->attached_dev;
+
-+ if (do_carrier)
++ if (do_carrier) {
+ if (up)
+ netif_carrier_on(netdev);
+ else if (!xrx200_phy_has_link(netdev))
+ netif_carrier_off(netdev);
++ }
+
+ phydev->adjust_link(netdev);
+}
+
+ /* store the port id in the hw struct so we can map ports -> devices */
+ priv->hw->port_map[p->num] = priv->hw->num_devs;
++
++ /* store the phy addr in the hw struct so we can map ports -> phys */
++ priv->hw->phy_addr[p->num] = p->phy_addr;
+}
+
+static const struct net_device_ops xrx200_netdev_ops = {
+ }
+
+ /* bring up the dma engine and IP core */
-+ xrx200_dma_init(&xrx200_hw);
++ xrx200_dma_init(&pdev->dev, &xrx200_hw);
+ xrx200_hw_init(&xrx200_hw);
+ tasklet_init(&xrx200_hw.chan[XRX200_DMA_TX].tasklet, xrx200_tx_housekeeping, (u32) &xrx200_hw.chan[XRX200_DMA_TX]);
+ tasklet_init(&xrx200_hw.chan[XRX200_DMA_TX_2].tasklet, xrx200_tx_housekeeping, (u32) &xrx200_hw.chan[XRX200_DMA_TX_2]);