From addf7b958d754b5c4a713f900f13eff4fccb6641 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 12 Nov 2014 14:54:50 +0000 Subject: ralink: add support for mt7621 ethernet somehow all switch ports still come up as 10mbit. Signed-off-by: John Crispin git-svn-id: svn://svn.openwrt.org/openwrt/trunk@43237 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../files/drivers/net/ethernet/ralink/Kconfig | 6 +- .../drivers/net/ethernet/ralink/gsw_mt7620a.c | 247 +++++++++++++++++++-- .../drivers/net/ethernet/ralink/gsw_mt7620a.h | 1 + .../files/drivers/net/ethernet/ralink/mt7530.c | 2 +- .../drivers/net/ethernet/ralink/ralink_soc_eth.c | 31 ++- .../drivers/net/ethernet/ralink/ralink_soc_eth.h | 6 + .../files/drivers/net/ethernet/ralink/soc_mt7620.c | 76 ++++++- .../files/drivers/net/ethernet/ralink/soc_rt305x.c | 1 + 8 files changed, 334 insertions(+), 36 deletions(-) (limited to 'target/linux/ramips/files') diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig b/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig index b25a12a128..22df4fe32f 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig @@ -22,11 +22,7 @@ config NET_RALINK_RT3883 config NET_RALINK_MT7620 bool "MT7620" - depends on SOC_MT7620 - -config NET_RALINK_MT7621 - bool "MT7621" - depends on SOC_MT7621 + depends on (SOC_MT7620 || SOC_MT7621) endchoice diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.c index c0ec939263..74fe0bb6ff 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.c @@ -50,7 +50,11 @@ #define GSW_REG_PHY_TIMEOUT (5 * HZ) +#ifdef CONFIG_SOC_MT7621 +#define MT7620A_GSW_REG_PIAC 0x0004 +#else #define MT7620A_GSW_REG_PIAC 0x7004 +#endif #define GSW_NUM_VLANS 16 #define GSW_NUM_VIDS 4096 @@ -74,13 +78,21 @@ #define GSW_REG_ISR 0x700c #define GSW_REG_GPC1 0x7014 +#define SYSC_REG_CHIP_REV_ID 0x0c #define SYSC_REG_CFG1 0x14 +#define SYSC_REG_RESET_CTRL 0x34 +#define RST_CTRL_MCM BIT(2) +#define SYSC_PAD_RGMII2_MDIO 0x58 +#define SYSC_GPIO_MODE 0x60 #define PORT_IRQ_ST_CHG 0x7f -#define SYSCFG1 0x14 +#ifdef CONFIG_SOC_MT7621 +#define ESW_PHY_POLLING 0x0000 +#else #define ESW_PHY_POLLING 0x7000 +#endif #define PMCR_IPG BIT(18) #define PMCR_MAC_MODE BIT(16) @@ -200,6 +212,26 @@ int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg) return _mt7620_mii_read(gsw, phy_addr, phy_reg); } +static void +mt7530_mdio_w32(struct mt7620_gsw *gsw, u32 reg, u32 val) +{ + _mt7620_mii_write(gsw, 0x1f, 0x1f, (reg >> 6) & 0x3ff); + _mt7620_mii_write(gsw, 0x1f, (reg >> 2) & 0xf, val & 0xffff); + _mt7620_mii_write(gsw, 0x1f, 0x10, val >> 16); +} + +static u32 +mt7530_mdio_r32(struct mt7620_gsw *gsw, u32 reg) +{ + u16 high, low; + + _mt7620_mii_write(gsw, 0x1f, 0x1f, (reg >> 6) & 0x3ff); + low = _mt7620_mii_read(gsw, 0x1f, (reg >> 2) & 0xf); + high = _mt7620_mii_read(gsw, 0x1f, 0x10); + + return (high << 16) | (low & 0xffff); +} + static unsigned char *fe_speed_str(int speed) { switch (speed) { @@ -250,7 +282,7 @@ void mt7620_mdio_link_adjust(struct fe_priv *priv, int port) mt7620a_handle_carrier(priv); } -static irqreturn_t gsw_interrupt(int irq, void *_priv) +static irqreturn_t gsw_interrupt_mt7620(int irq, void *_priv) { struct fe_priv *priv = (struct fe_priv *) _priv; struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv; @@ -281,6 +313,33 @@ static irqreturn_t gsw_interrupt(int irq, void *_priv) return IRQ_HANDLED; } +static irqreturn_t gsw_interrupt_mt7621(int irq, void *_priv) +{ + struct fe_priv *priv = (struct fe_priv *) _priv; + struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv; + u32 reg, i; + + reg = mt7530_mdio_r32(gsw, 0x700c); + + for (i = 0; i < 5; i++) + if (reg & BIT(i)) { + unsigned int link = mt7530_mdio_r32(gsw, 0x3008 + (i * 0x100)) & 0x1; + + if (link != priv->link[i]) { + priv->link[i] = link; + if (link) + netdev_info(priv->netdev, "port %d link up\n", i); + else + netdev_info(priv->netdev, "port %d link down\n", i); + } + } + + mt7620a_handle_carrier(priv); + mt7530_mdio_w32(gsw, 0x700c, 0x1f); + + return IRQ_HANDLED; +} + static int mt7620_is_bga(void) { u32 bga = rt_sysc_r32(0x0c); @@ -299,7 +358,7 @@ static void gsw_auto_poll(struct mt7620_gsw *gsw) msb = phy; } - if (lsb) + if (lsb == msb) lsb--; gsw_w32(gsw, PHY_AN_EN | PHY_PRE_EN | PMY_MDC_CONF(5) | (msb << 8) | lsb, ESW_PHY_POLLING); @@ -354,10 +413,10 @@ void mt7620_port_init(struct fe_priv *priv, struct device_node *np) if (!priv->phy->phy_node[id] && !priv->phy->phy_fixed[id]) return; - val = rt_sysc_r32(SYSCFG1); + val = rt_sysc_r32(SYSC_REG_CFG1); val &= ~(3 << shift); val |= mask << shift; - rt_sysc_w32(val, SYSCFG1); + rt_sysc_w32(val, SYSC_REG_CFG1); if (priv->phy->phy_fixed[id]) { const __be32 *link = priv->phy->phy_fixed[id]; @@ -411,7 +470,7 @@ void mt7620_port_init(struct fe_priv *priv, struct device_node *np) } } -static void gsw_hw_init(struct mt7620_gsw *gsw, struct device_node *np) +static void gsw_hw_init_mt7620(struct mt7620_gsw *gsw, struct device_node *np) { u32 is_BGA = mt7620_is_bga(); @@ -487,9 +546,9 @@ static void gsw_hw_init(struct mt7620_gsw *gsw, struct device_node *np) /* setup port 4 */ if (gsw->port4 == PORT4_EPHY) { - u32 val = rt_sysc_r32(SYSCFG1); + u32 val = rt_sysc_r32(SYSC_REG_CFG1); val |= 3 << 14; - rt_sysc_w32(val, SYSCFG1); + rt_sysc_w32(val, SYSC_REG_CFG1); _mt7620_mii_write(gsw, 4, 30, 0xa000); _mt7620_mii_write(gsw, 4, 4, 0x05e1); _mt7620_mii_write(gsw, 4, 16, 0x1313); @@ -497,6 +556,145 @@ static void gsw_hw_init(struct mt7620_gsw *gsw, struct device_node *np) } } +static void gsw_hw_init_mt7621(struct mt7620_gsw *gsw, struct device_node *np) +{ + u32 i; + u32 val; + + /* Hardware reset Switch */ + val = rt_sysc_r32(SYSC_REG_RESET_CTRL); + rt_sysc_w32(val | RST_CTRL_MCM, SYSC_REG_RESET_CTRL); + udelay(1000); + rt_sysc_w32(val, SYSC_REG_RESET_CTRL); + udelay(10000); + + /* reduce RGMII2 PAD driving strength */ + rt_sysc_m32(3 << 4, 0, SYSC_PAD_RGMII2_MDIO); + + /* gpio mux - RGMII1=Normal mode */ + rt_sysc_m32(BIT(14), 0, SYSC_GPIO_MODE); + + //GMAC1= RGMII mode + rt_sysc_m32(3 << 12, 0, SYSC_REG_CFG1); + + /* enable MDIO to control MT7530 */ + rt_sysc_m32(3 << 12, 0, SYSC_GPIO_MODE); + + /* turn off all PHYs */ + for (i = 0; i <= 4; i++) { + _mt7620_mii_read(gsw, i, 0x0); + val |= (0x1 << 11); + _mt7620_mii_write(gsw, i, 0x0, val); + } + + /* reset the switch */ + mt7530_mdio_w32(gsw, 0x7000, 0x3); + udelay(10); + + if ((rt_sysc_r32(SYSC_REG_CHIP_REV_ID) & 0xFFFF) == 0x0101) { + /* (GE1, Force 1000M/FD, FC ON) */ + gsw_w32(gsw, 0x2005e30b, 0x100); + mt7530_mdio_w32(gsw, 0x3600, 0x5e30b); + } else { + /* (GE1, Force 1000M/FD, FC ON) */ + gsw_w32(gsw, 0x2005e33b, 0x100); + mt7530_mdio_w32(gsw, 0x3600, 0x5e33b); + } + + /* (GE2, Link down) */ + gsw_w32(gsw, 0x8000, 0x200); + + //val = 0x117ccf; //Enable Port 6, P5 as GMAC5, P5 disable + val = mt7530_mdio_r32(gsw, 0x7804); + val &= ~(1<<8); //Enable Port 6 + val |= (1<<6); //Disable Port 5 + val |= (1<<13); //Port 5 as GMAC, no Internal PHY + + val |= (1<<16);//change HW-TRAP + printk("change HW-TRAP to 0x%x\n", val); + mt7530_mdio_w32(gsw, 0x7804, val); + + val = rt_sysc_r32(0x10); + val = (val >> 6) & 0x7; + if (val >= 6) { + /* 25Mhz Xtal - do nothing */ + } else if(val >=3) { + /* 40Mhz */ + + /* disable MT7530 core clock */ + _mt7620_mii_write(gsw, 0, 13, 0x1f); + _mt7620_mii_write(gsw, 0, 14, 0x410); + _mt7620_mii_write(gsw, 0, 13, 0x401f); + _mt7620_mii_write(gsw, 0, 14, 0x0); + + /* disable MT7530 PLL */ + _mt7620_mii_write(gsw, 0, 13, 0x1f); + _mt7620_mii_write(gsw, 0, 14, 0x40d); + _mt7620_mii_write(gsw, 0, 13, 0x401f); + _mt7620_mii_write(gsw, 0, 14, 0x2020); + + /* for MT7530 core clock = 500Mhz */ + _mt7620_mii_write(gsw, 0, 13, 0x1f); + _mt7620_mii_write(gsw, 0, 14, 0x40e); + _mt7620_mii_write(gsw, 0, 13, 0x401f); + _mt7620_mii_write(gsw, 0, 14, 0x119); + + /* enable MT7530 PLL */ + _mt7620_mii_write(gsw, 0, 13, 0x1f); + _mt7620_mii_write(gsw, 0, 14, 0x40d); + _mt7620_mii_write(gsw, 0, 13, 0x401f); + _mt7620_mii_write(gsw, 0, 14, 0x2820); + + udelay(20); + + /* enable MT7530 core clock */ + _mt7620_mii_write(gsw, 0, 13, 0x1f); + _mt7620_mii_write(gsw, 0, 14, 0x410); + _mt7620_mii_write(gsw, 0, 13, 0x401f); + } else { + /* 20Mhz Xtal - TODO */ + } + + /* RGMII */ + _mt7620_mii_write(gsw, 0, 14, 0x1); + + /* set MT7530 central align */ + val = mt7530_mdio_r32(gsw, 0x7830); + val &= ~1; + val |= 1<<1; + mt7530_mdio_w32(gsw, 0x7830, val); + + val = mt7530_mdio_r32(gsw, 0x7a40); + val &= ~(1<<30); + mt7530_mdio_w32(gsw, 0x7a40, val); + + mt7530_mdio_w32(gsw, 0x7a78, 0x855); + mt7530_mdio_w32(gsw, 0x7b00, 0x102); //delay setting for 10/1000M + mt7530_mdio_w32(gsw, 0x7b04, 0x14); //delay setting for 10/1000M + + /*Tx Driving*/ + mt7530_mdio_w32(gsw, 0x7a54, 0x44); //lower driving + mt7530_mdio_w32(gsw, 0x7a5c, 0x44); //lower driving + mt7530_mdio_w32(gsw, 0x7a64, 0x44); //lower driving + mt7530_mdio_w32(gsw, 0x7a6c, 0x44); //lower driving + mt7530_mdio_w32(gsw, 0x7a74, 0x44); //lower driving + mt7530_mdio_w32(gsw, 0x7a7c, 0x44); //lower driving + + //LANWANPartition(); + + /* turn on all PHYs */ + for (i = 0; i <= 4; i++) { + val = _mt7620_mii_read(gsw, i, 0); + val &= ~BIT(11); + _mt7620_mii_write(gsw, i, 0, val); + } + + /* enable irq */ + val = mt7530_mdio_r32(gsw, 0x7808); + val |= 3 << 16; + mt7530_mdio_w32(gsw, 0x7808, val); +} + void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac) { struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv; @@ -529,6 +727,14 @@ int mt7620_gsw_config(struct fe_priv *priv) return 0; } +int mt7621_gsw_config(struct fe_priv *priv) +{ + if (priv->mii_bus && priv->mii_bus->phy_map[0x1f]) + mt7530_probe(priv->device, NULL, priv->mii_bus, 1); + + return 0; +} + int mt7620_gsw_probe(struct fe_priv *priv) { struct mt7620_gsw *gsw; @@ -548,12 +754,6 @@ int mt7620_gsw_probe(struct fe_priv *priv) return -ENOMEM; } - gsw->irq = irq_of_parse_and_map(np, 0); - if (!gsw->irq) { - dev_err(priv->device, "no gsw irq resource found\n"); - return -ENOMEM; - } - gsw->base = of_iomap(np, 0); if (!gsw->base) { dev_err(priv->device, "gsw ioremap failed\n"); @@ -569,12 +769,23 @@ int mt7620_gsw_probe(struct fe_priv *priv) else if (port4 && !strcmp(port4, "gmac")) gsw->port4 = PORT4_EXT; else - WARN_ON(port4); + gsw->port4 = PORT4_EPHY; - gsw_hw_init(gsw, np); + if (IS_ENABLED(CONFIG_SOC_MT7620)) + gsw_hw_init_mt7620(gsw, np); + else + gsw_hw_init_mt7621(gsw, np); - gsw_w32(gsw, ~PORT_IRQ_ST_CHG, GSW_REG_IMR); - request_irq(gsw->irq, gsw_interrupt, 0, "gsw", priv); + gsw->irq = irq_of_parse_and_map(np, 0); + if (gsw->irq) { + if (IS_ENABLED(CONFIG_SOC_MT7620)) { + request_irq(gsw->irq, gsw_interrupt_mt7620, 0, "gsw", priv); + gsw_w32(gsw, ~PORT_IRQ_ST_CHG, GSW_REG_IMR); + } else { + request_irq(gsw->irq, gsw_interrupt_mt7621, 0, "gsw", priv); + mt7530_mdio_w32(gsw, 0x7008, 0x1f); + } + } return 0; } diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.h index c87761ac06..d75adf92fa 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.h +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.h @@ -19,6 +19,7 @@ #define _RALINK_GSW_MT7620_H__ extern int mt7620_gsw_config(struct fe_priv *priv); +extern int mt7621_gsw_config(struct fe_priv *priv); extern int mt7620_gsw_probe(struct fe_priv *priv); extern void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac); extern int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val); diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c index c840953a54..1352b2518b 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c @@ -578,7 +578,7 @@ mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vl mt7530_apply_config(swdev); /* magic vodoo */ - if (bus && mt7530_r32(mt7530, REG_HWTRAP) != 0x1117edf) { + if (!IS_ENABLED(CONFIG_SOC_MT7621) && bus && mt7530_r32(mt7530, REG_HWTRAP) != 0x1117edf) { dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n"); mt7530_w32(mt7530, REG_HWTRAP, 0x1117edf); } diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c index caf4e5393e..f09751040b 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c @@ -79,6 +79,7 @@ static const u32 fe_reg_table_default[FE_REG_COUNT] = { [FE_REG_FE_INT_STATUS] = FE_FE_INT_STATUS, [FE_REG_FE_DMA_VID_BASE] = FE_DMA_VID0, [FE_REG_FE_COUNTER_BASE] = FE_GDMA1_TX_GBCNT, + [FE_REG_FE_RST_GL] = FE_FE_RST_GL, }; static const u32 *fe_reg_table = fe_reg_table_default; @@ -390,10 +391,17 @@ static struct rtnl_link_stats64 *fe_get_stats64(struct net_device *dev, do { start = u64_stats_fetch_begin_bh(&hwstats->syncp); - storage->rx_packets = hwstats->rx_packets; - storage->tx_packets = hwstats->tx_packets; - storage->rx_bytes = hwstats->rx_bytes; - storage->tx_bytes = hwstats->tx_bytes; + if (IS_ENABLED(CONFIG_SOC_MT7621)) { + storage->rx_packets = dev->stats.rx_packets; + storage->tx_packets = dev->stats.tx_packets; + storage->rx_bytes = dev->stats.rx_bytes; + storage->tx_bytes = dev->stats.tx_bytes; + } else { + storage->rx_packets = dev->stats.rx_packets; + storage->tx_packets = dev->stats.tx_packets; + storage->rx_bytes = dev->stats.rx_bytes; + storage->tx_bytes = dev->stats.tx_bytes; + } storage->collisions = hwstats->tx_collisions; storage->rx_length_errors = hwstats->rx_short_errors + hwstats->rx_long_errors; @@ -441,9 +449,12 @@ static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev, /* VLAN header offload */ if (vlan_tx_tag_present(skb)) { - txd->txd4 |= TX_DMA_INS_VLAN | - ((vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT) << 4) | - (vlan_tx_tag_get(skb) & 0xF); + if (IS_ENABLED(CONFIG_SOC_MT7620)) + txd->txd4 |= TX_DMA_INS_VLAN | + ((vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT) << 4) | + (vlan_tx_tag_get(skb) & 0xF); + else + txd->txd4 |= TX_DMA_INS_VLAN_MT7621 | vlan_tx_tag_get(skb); } /* TSO: fill MSS info in tcp checksum field */ @@ -951,8 +962,10 @@ static int fe_hw_init(struct net_device *dev) if (priv->soc->fwd_config(priv)) netdev_err(dev, "unable to get clock\n"); - fe_w32(1, FE_FE_RST_GL); - fe_w32(0, FE_FE_RST_GL); + if (fe_reg_table[FE_REG_FE_RST_GL]) { + fe_reg_w32(1, FE_REG_FE_RST_GL); + fe_reg_w32(0, FE_REG_FE_RST_GL); + } return 0; } diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.h index e5171b25e3..67d5ce65cf 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.h +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.h @@ -40,6 +40,7 @@ enum fe_reg { FE_REG_FE_INT_STATUS, FE_REG_FE_DMA_VID_BASE, FE_REG_FE_COUNTER_BASE, + FE_REG_FE_RST_GL, FE_REG_COUNT }; @@ -125,7 +126,11 @@ enum fe_reg { #define FE_CDMA_CSG_CFG (FE_CDMA_OFFSET + 0x00) #define FE_CDMA_SCH_CFG (FE_CDMA_OFFSET + 0x04) +#ifdef CONFIG_SOC_MT7621 +#define MT7620A_GDMA_OFFSET 0x0500 +#else #define MT7620A_GDMA_OFFSET 0x0600 +#endif #define MT7620A_GDMA1_FWD_CFG (MT7620A_GDMA_OFFSET + 0x00) #define MT7620A_FE_GDMA1_SCH_CFG (MT7620A_GDMA_OFFSET + 0x04) #define MT7620A_FE_GDMA1_SHPR_CFG (MT7620A_GDMA_OFFSET + 0x08) @@ -294,6 +299,7 @@ struct fe_rx_dma { #define TX_DMA_LS0 BIT(30) #define TX_DMA_DONE BIT(31) +#define TX_DMA_INS_VLAN_MT7621 BIT(16) #define TX_DMA_INS_VLAN BIT(7) #define TX_DMA_INS_PPPOE BIT(12) #define TX_DMA_QN(_x) ((_x) << 16) diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c index a949e9feec..2f3018d6a4 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c @@ -29,10 +29,13 @@ #define MT7620_DMA_VID (MT7620A_CDMA_CSG_CFG | 0x30) #define MT7620A_DMA_2B_OFFSET BIT(31) #define MT7620A_RESET_FE BIT(21) +#define MT7621_RESET_FE BIT(6) #define MT7620A_RESET_ESW BIT(23) #define MT7620_L4_VALID BIT(23) +#define MT7621_L4_VALID BIT(24) #define MT7620_TX_DMA_UDF BIT(15) +#define MT7621_TX_DMA_UDF BIT(19) #define TX_DMA_FP_BMAP ((0xff) << 19) #define SYSC_REG_RESET_CTRL 0x34 @@ -51,6 +54,11 @@ #define MT7620_GDM1_TX_GBCNT (MT7620_REG_MIB_OFFSET + 0x300) #define MT7620_GDM2_TX_GBCNT (MT7620_GDM1_TX_GBCNT + 0x40) +#define GSW_REG_GDMA1_MAC_ADRL 0x508 +#define GSW_REG_GDMA1_MAC_ADRH 0x50C + +#define MT7621_FE_RST_GL (FE_FE_OFFSET + 0x04) + static const u32 mt7620_reg_table[FE_REG_COUNT] = { [FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG, [FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG, @@ -65,12 +73,23 @@ static const u32 mt7620_reg_table[FE_REG_COUNT] = { [FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS, [FE_REG_FE_DMA_VID_BASE] = MT7620_DMA_VID, [FE_REG_FE_COUNTER_BASE] = MT7620_GDM1_TX_GBCNT, + [FE_REG_FE_RST_GL] = MT7621_FE_RST_GL, }; static void mt7620_fe_reset(void) { - rt_sysc_w32(MT7620A_RESET_FE | MT7620A_RESET_ESW, SYSC_REG_RESET_CTRL); - rt_sysc_w32(0, SYSC_REG_RESET_CTRL); + u32 val = rt_sysc_r32(SYSC_REG_RESET_CTRL); + + rt_sysc_w32(val | MT7620A_RESET_FE | MT7620A_RESET_ESW, SYSC_REG_RESET_CTRL); + rt_sysc_w32(val, SYSC_REG_RESET_CTRL); +} + +static void mt7621_fe_reset(void) +{ + u32 val = rt_sysc_r32(SYSC_REG_RESET_CTRL); + + rt_sysc_w32(val | MT7621_RESET_FE, SYSC_REG_RESET_CTRL); + rt_sysc_w32(val, SYSC_REG_RESET_CTRL); } static void mt7620_rxcsum_config(bool enable) @@ -109,11 +128,28 @@ static int mt7620_fwd_config(struct fe_priv *priv) return 0; } +static int mt7621_fwd_config(struct fe_priv *priv) +{ + struct net_device *dev = priv_netdev(priv); + + fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~0xffff, MT7620A_GDMA1_FWD_CFG); + + mt7620_txcsum_config((dev->features & NETIF_F_IP_CSUM)); + mt7620_rxcsum_config((dev->features & NETIF_F_RXCSUM)); + + return 0; +} + static void mt7620_tx_dma(struct fe_priv *priv, int idx, struct sk_buff *skb) { priv->tx_dma[idx].txd4 = 0; } +static void mt7621_tx_dma(struct fe_priv *priv, int idx, struct sk_buff *skb) +{ + priv->tx_dma[idx].txd4 = BIT(25); +} + static void mt7620_rx_dma(struct fe_priv *priv, int idx, int len) { priv->rx_dma[idx].rxd2 = RX_DMA_PLEN0(len); @@ -128,11 +164,22 @@ static void mt7620_init_data(struct fe_soc_data *data, netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_TX; - if (mt7620_get_eco() >= 5) + if (mt7620_get_eco() >= 5 || IS_ENABLED(CONFIG_SOC_MT7621)) netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_IPV6_CSUM; } +static void mt7621_set_mac(struct fe_priv *priv, unsigned char *mac) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->page_lock, flags); + fe_w32((mac[0] << 8) | mac[1], GSW_REG_GDMA1_MAC_ADRH); + fe_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], + GSW_REG_GDMA1_MAC_ADRL); + spin_unlock_irqrestore(&priv->page_lock, flags); +} + static struct fe_soc_data mt7620_data = { .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }, .init_data = mt7620_init_data, @@ -156,8 +203,31 @@ static struct fe_soc_data mt7620_data = { .mdio_adjust_link = mt7620_mdio_link_adjust, }; +static struct fe_soc_data mt7621_data = { + .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }, + .init_data = mt7620_init_data, + .reset_fe = mt7621_fe_reset, + .set_mac = mt7621_set_mac, + .fwd_config = mt7621_fwd_config, + .tx_dma = mt7621_tx_dma, + .rx_dma = mt7620_rx_dma, + .switch_init = mt7620_gsw_probe, + .switch_config = mt7621_gsw_config, + .reg_table = mt7620_reg_table, + .pdma_glo_cfg = FE_PDMA_SIZE_16DWORDS | MT7620A_DMA_2B_OFFSET, + .rx_dly_int = RT5350_RX_DLY_INT, + .tx_dly_int = RT5350_TX_DLY_INT, + .checksum_bit = MT7621_L4_VALID, + .tx_udf_bit = MT7621_TX_DMA_UDF, + .has_carrier = mt7620a_has_carrier, + .mdio_read = mt7620_mdio_read, + .mdio_write = mt7620_mdio_write, + .mdio_adjust_link = mt7620_mdio_link_adjust, +}; + const struct of_device_id of_fe_match[] = { { .compatible = "ralink,mt7620a-eth", .data = &mt7620_data }, + { .compatible = "ralink,mt7621-eth", .data = &mt7621_data }, {}, }; diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt305x.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt305x.c index aff6253432..c406013228 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt305x.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt305x.c @@ -51,6 +51,7 @@ static const u32 rt5350_reg_table[FE_REG_COUNT] = { [FE_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0, [FE_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE, [FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS, + [FE_REG_FE_RST_GL] = 0, [FE_REG_FE_DMA_VID_BASE] = 0, }; -- cgit v1.2.3