diff options
Diffstat (limited to 'target/linux/lantiq/patches-3.2/0018-NET-MIPS-lantiq-make-etop-ethernet-work-on-ase-ar9.patch')
-rw-r--r-- | target/linux/lantiq/patches-3.2/0018-NET-MIPS-lantiq-make-etop-ethernet-work-on-ase-ar9.patch | 396 |
1 files changed, 0 insertions, 396 deletions
diff --git a/target/linux/lantiq/patches-3.2/0018-NET-MIPS-lantiq-make-etop-ethernet-work-on-ase-ar9.patch b/target/linux/lantiq/patches-3.2/0018-NET-MIPS-lantiq-make-etop-ethernet-work-on-ase-ar9.patch deleted file mode 100644 index b858c40155..0000000000 --- a/target/linux/lantiq/patches-3.2/0018-NET-MIPS-lantiq-make-etop-ethernet-work-on-ase-ar9.patch +++ /dev/null @@ -1,396 +0,0 @@ -From a1a9dcf7554df9bbf23ca0933e645b2327abbb8b Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Wed, 10 Aug 2011 15:32:16 +0200 -Subject: [PATCH 18/73] NET: MIPS: lantiq: make etop ethernet work on ase/ar9 - -Extend the driver to handle the different DMA channel layout for AR9 and -Amazon-SE SoCs. The patch also adds support for the integrated PHY found -on Amazon-SE and the gigabit switch found inside the AR9. - -Signed-off-by: John Crispin <blogic@openwrt.org> -Cc: netdev@vger.kernel.org ---- - .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 22 +--- - .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 10 ++ - arch/mips/lantiq/xway/devices.c | 11 +- - drivers/net/ethernet/lantiq_etop.c | 171 ++++++++++++++++++-- - 4 files changed, 174 insertions(+), 40 deletions(-) - ---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h -+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h -@@ -38,26 +38,8 @@ - - #define MIPS_CPU_TIMER_IRQ 7 - --#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0) --#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1) --#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2) --#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3) --#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4) --#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5) --#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6) --#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7) --#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8) --#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9) --#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10) --#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11) --#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25) --#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26) --#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27) --#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28) --#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29) --#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30) --#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16) --#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21) -+#define LTQ_DMA_ETOP ((ltq_is_ase()) ? \ -+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0)) - - #define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24) - ---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -@@ -82,6 +82,7 @@ - #define LTQ_PMU_SIZE 0x1000 - - #define PMU_DMA 0x0020 -+#define PMU_EPHY 0x0080 - #define PMU_USB 0x8041 - #define PMU_LED 0x0800 - #define PMU_GPT 0x1000 -@@ -93,6 +94,10 @@ - #define LTQ_ETOP_BASE_ADDR 0x1E180000 - #define LTQ_ETOP_SIZE 0x40000 - -+/* GBIT - gigabit switch */ -+#define LTQ_GBIT_BASE_ADDR 0x1E108000 -+#define LTQ_GBIT_SIZE 0x200 -+ - /* DMA */ - #define LTQ_DMA_BASE_ADDR 0x1E104100 - #define LTQ_DMA_SIZE 0x800 -@@ -147,6 +152,11 @@ extern void ltq_pmu_enable(unsigned int - extern void ltq_pmu_disable(unsigned int module); - extern void ltq_cgu_enable(unsigned int clk); - -+static inline int ltq_is_ase(void) -+{ -+ return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE); -+} -+ - static inline int ltq_is_ar9(void) - { - return (ltq_get_soc_type() == SOC_TYPE_AR9); ---- a/arch/mips/lantiq/xway/devices.c -+++ b/arch/mips/lantiq/xway/devices.c -@@ -74,18 +74,23 @@ void __init ltq_register_ase_asc(void) - } - - /* ethernet */ --static struct resource ltq_etop_resources = -- MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE); -+static struct resource ltq_etop_resources[] = { -+ MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE), -+ MEM_RES("gbit", LTQ_GBIT_BASE_ADDR, LTQ_GBIT_SIZE), -+}; - - static struct platform_device ltq_etop = { - .name = "ltq_etop", -- .resource = <q_etop_resources, -+ .resource = ltq_etop_resources, - .num_resources = 1, - }; - - void __init - ltq_register_etop(struct ltq_eth_data *eth) - { -+ /* only register the gphy on socs that have one */ -+ if (ltq_is_ar9() | ltq_is_vr9()) -+ ltq_etop.num_resources = 2; - if (eth) { - ltq_etop.dev.platform_data = eth; - platform_device_register(<q_etop); ---- a/drivers/net/ethernet/lantiq_etop.c -+++ b/drivers/net/ethernet/lantiq_etop.c -@@ -71,10 +71,43 @@ - #define ETOP_MII_REVERSE 0xe - #define ETOP_PLEN_UNDER 0x40 - #define ETOP_CGEN 0x800 -+#define ETOP_CFG_MII0 0x01 - --/* use 2 static channels for TX/RX */ -+#define LTQ_GBIT_MDIO_CTL 0xCC -+#define LTQ_GBIT_MDIO_DATA 0xd0 -+#define LTQ_GBIT_GCTL0 0x68 -+#define LTQ_GBIT_PMAC_HD_CTL 0x8c -+#define LTQ_GBIT_P0_CTL 0x4 -+#define LTQ_GBIT_PMAC_RX_IPG 0xa8 -+ -+#define PMAC_HD_CTL_AS (1 << 19) -+#define PMAC_HD_CTL_RXSH (1 << 22) -+ -+/* Switch Enable (0=disable, 1=enable) */ -+#define GCTL0_SE 0x80000000 -+/* Disable MDIO auto polling (0=disable, 1=enable) */ -+#define PX_CTL_DMDIO 0x00400000 -+ -+/* register information for the gbit's MDIO bus */ -+#define MDIO_XR9_REQUEST 0x00008000 -+#define MDIO_XR9_READ 0x00000800 -+#define MDIO_XR9_WRITE 0x00000400 -+#define MDIO_XR9_REG_MASK 0x1f -+#define MDIO_XR9_ADDR_MASK 0x1f -+#define MDIO_XR9_RD_MASK 0xffff -+#define MDIO_XR9_REG_OFFSET 0 -+#define MDIO_XR9_ADDR_OFFSET 5 -+#define MDIO_XR9_WR_OFFSET 16 -+ -+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */ -+#define ltq_has_gbit() (ltq_is_ar9() || ltq_is_vr9()) -+ -+/* use 2 static channels for TX/RX -+ depending on the SoC we need to use different DMA channels for ethernet */ - #define LTQ_ETOP_TX_CHANNEL 1 --#define LTQ_ETOP_RX_CHANNEL 6 -+#define LTQ_ETOP_RX_CHANNEL ((ltq_is_ase()) ? (5) : \ -+ ((ltq_has_gbit()) ? (0) : (6))) -+ - #define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL) - #define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL) - -@@ -83,9 +116,15 @@ - #define ltq_etop_w32_mask(x, y, z) \ - ltq_w32_mask(x, y, ltq_etop_membase + (z)) - -+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x)) -+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y)) -+#define ltq_gbit_w32_mask(x, y, z) \ -+ ltq_w32_mask(x, y, ltq_gbit_membase + (z)) -+ - #define DRV_VERSION "1.0" - - static void __iomem *ltq_etop_membase; -+static void __iomem *ltq_gbit_membase; - - struct ltq_etop_chan { - int idx; -@@ -110,6 +149,9 @@ struct ltq_etop_priv { - spinlock_t lock; - }; - -+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, -+ int phy_reg, u16 phy_data); -+ - static int - ltq_etop_alloc_skb(struct ltq_etop_chan *ch) - { -@@ -211,7 +253,7 @@ static irqreturn_t - ltq_etop_dma_irq(int irq, void *_priv) - { - struct ltq_etop_priv *priv = _priv; -- int ch = irq - LTQ_DMA_CH0_INT; -+ int ch = irq - LTQ_DMA_ETOP; - - napi_schedule(&priv->ch[ch].napi); - return IRQ_HANDLED; -@@ -244,15 +286,43 @@ ltq_etop_hw_exit(struct net_device *dev) - ltq_etop_free_channel(dev, &priv->ch[i]); - } - -+static void -+ltq_etop_gbit_init(void) -+{ -+ ltq_pmu_enable(PMU_SWITCH); -+ -+ ltq_gpio_request(42, 2, 1, "MDIO"); -+ ltq_gpio_request(43, 2, 1, "MDC"); -+ -+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0); -+ /** Disable MDIO auto polling mode */ -+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL); -+ /* set 1522 packet size */ -+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0); -+ /* disable pmac & dmac headers */ -+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0, -+ LTQ_GBIT_PMAC_HD_CTL); -+ /* Due to traffic halt when burst length 8, -+ replace default IPG value with 0x3B */ -+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG); -+} -+ - static int - ltq_etop_hw_init(struct net_device *dev) - { - struct ltq_etop_priv *priv = netdev_priv(dev); -+ unsigned int mii_mode = priv->pldata->mii_mode; - int i; - - ltq_pmu_enable(PMU_PPE); - -- switch (priv->pldata->mii_mode) { -+ if (ltq_has_gbit()) { -+ ltq_etop_gbit_init(); -+ /* force the etops link to the gbit to MII */ -+ mii_mode = PHY_INTERFACE_MODE_MII; -+ } -+ -+ switch (mii_mode) { - case PHY_INTERFACE_MODE_RMII: - ltq_etop_w32_mask(ETOP_MII_MASK, - ETOP_MII_REVERSE, LTQ_ETOP_CFG); -@@ -264,6 +334,18 @@ ltq_etop_hw_init(struct net_device *dev) - break; - - default: -+ if (ltq_is_ase()) { -+ ltq_pmu_enable(PMU_EPHY); -+ /* disable external MII */ -+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG); -+ /* enable clock for internal PHY */ -+ ltq_cgu_enable(CGU_EPHY); -+ /* we need to write this magic to the internal phy to -+ make it work */ -+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020); -+ pr_info("Selected EPHY mode\n"); -+ break; -+ } - netdev_err(dev, "unknown mii mode %d\n", - priv->pldata->mii_mode); - return -ENOTSUPP; -@@ -275,7 +357,7 @@ ltq_etop_hw_init(struct net_device *dev) - ltq_dma_init_port(DMA_PORT_ETOP); - - for (i = 0; i < MAX_DMA_CHAN; i++) { -- int irq = LTQ_DMA_CH0_INT + i; -+ int irq = LTQ_DMA_ETOP + i; - struct ltq_etop_chan *ch = &priv->ch[i]; - - ch->idx = ch->dma.nr = i; -@@ -339,6 +421,39 @@ static const struct ethtool_ops ltq_etop - }; - - static int -+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr, -+ int phy_reg, u16 phy_data) -+{ -+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE | -+ (phy_data << MDIO_XR9_WR_OFFSET) | -+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) | -+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET); -+ -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL); -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ return 0; -+} -+ -+static int -+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg) -+{ -+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ | -+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) | -+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET); -+ -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL); -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK; -+ return val; -+} -+ -+static int - ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data) - { - u32 val = MDIO_REQUEST | -@@ -379,14 +494,11 @@ ltq_etop_mdio_probe(struct net_device *d - { - struct ltq_etop_priv *priv = netdev_priv(dev); - struct phy_device *phydev = NULL; -- int phy_addr; - -- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -- if (priv->mii_bus->phy_map[phy_addr]) { -- phydev = priv->mii_bus->phy_map[phy_addr]; -- break; -- } -- } -+ if (ltq_is_ase()) -+ phydev = priv->mii_bus->phy_map[8]; -+ else -+ phydev = priv->mii_bus->phy_map[0]; - - if (!phydev) { - netdev_err(dev, "no PHY found\n"); -@@ -408,6 +520,9 @@ ltq_etop_mdio_probe(struct net_device *d - | SUPPORTED_Autoneg - | SUPPORTED_MII - | SUPPORTED_TP); -+ if (ltq_has_gbit()) -+ phydev->supported &= SUPPORTED_1000baseT_Half -+ | SUPPORTED_1000baseT_Full; - - phydev->advertising = phydev->supported; - priv->phydev = phydev; -@@ -433,8 +548,13 @@ ltq_etop_mdio_init(struct net_device *de - } - - priv->mii_bus->priv = dev; -- priv->mii_bus->read = ltq_etop_mdio_rd; -- priv->mii_bus->write = ltq_etop_mdio_wr; -+ if (ltq_has_gbit()) { -+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9; -+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9; -+ } else { -+ priv->mii_bus->read = ltq_etop_mdio_rd; -+ priv->mii_bus->write = ltq_etop_mdio_wr; -+ } - priv->mii_bus->name = "ltq_mii"; - snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); - priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); -@@ -524,9 +644,9 @@ ltq_etop_tx(struct sk_buff *skb, struct - struct ltq_etop_priv *priv = netdev_priv(dev); - struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1]; - struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; -- int len; - unsigned long flags; - u32 byte_offset; -+ int len; - - len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; - -@@ -700,7 +820,7 @@ ltq_etop_probe(struct platform_device *p - { - struct net_device *dev; - struct ltq_etop_priv *priv; -- struct resource *res; -+ struct resource *res, *gbit_res; - int err; - int i; - -@@ -728,6 +848,23 @@ ltq_etop_probe(struct platform_device *p - goto err_out; - } - -+ if (ltq_has_gbit()) { -+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!gbit_res) { -+ dev_err(&pdev->dev, "failed to get gbit resource\n"); -+ err = -ENOENT; -+ goto err_out; -+ } -+ ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev, -+ gbit_res->start, resource_size(gbit_res)); -+ if (!ltq_gbit_membase) { -+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n", -+ pdev->id); -+ err = -ENOMEM; -+ goto err_out; -+ } -+ } -+ - dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4); - strcpy(dev->name, "eth%d"); - dev->netdev_ops = <q_eth_netdev_ops; |