aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ramips/files
diff options
context:
space:
mode:
authorJohn Crispin <john@openwrt.org>2014-11-12 14:54:50 +0000
committerJohn Crispin <john@openwrt.org>2014-11-12 14:54:50 +0000
commit86e3315ecee80c6cd0b0728e119866f735d4f910 (patch)
treee4cf03081b1d3cf0e5889d75f66fd9c521d36b98 /target/linux/ramips/files
parent45814d150a90b9f0067cda87536349339ff675f5 (diff)
downloadupstream-86e3315ecee80c6cd0b0728e119866f735d4f910.tar.gz
upstream-86e3315ecee80c6cd0b0728e119866f735d4f910.tar.bz2
upstream-86e3315ecee80c6cd0b0728e119866f735d4f910.zip
ralink: add support for mt7621 ethernet
somehow all switch ports still come up as 10mbit. Signed-off-by: John Crispin <blogic@openwrt.org> SVN-Revision: 43237
Diffstat (limited to 'target/linux/ramips/files')
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig6
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.c247
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620a.h1
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c2
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c31
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.h6
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c76
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt305x.c1
8 files changed, 334 insertions, 36 deletions
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,
};