diff mbox series

[OpenWrt-Devel,RFC,4/9] mt7621: import mtk_eth_soc and mt7530 patches from the mediatek target

Message ID 20181015102503.30731-5-bjorn@mork.no
State RFC
Delegated to: John Crispin
Headers show
Series Using the mainline mtk-eth-soc driver for MT7621 | expand

Commit Message

Bjørn Mork Oct. 15, 2018, 10:24 a.m. UTC
This syncronizes most of the mtk_eth_soc and mt7530 patches between the two
targets, with the following exception:

 0045-net-dsa-mediatek-turn-into-platform-driver.patch

which will require more changes to the mt7621 device-trees than the
absolute minimum.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 .../0027-net-next-mediatek-fix-DQL-support.patch   |  92 +++++++
 ...iatek-add-support-for-GMAC2-wired-to-ext-.patch |  26 ++
 .../ramips/patches-4.14/0033-dsa-multi-cpu.patch   | 268 +++++++++++++++++++++
 ...5-net-mediatek-disable-RX-VLan-offloading.patch |  47 ++++
 ...diatek-honour-special-tag-bit-inside-RX-D.patch |  50 ++++
 ...diatek-enable-special-tag-indication-for-.patch |  41 ++++
 ...a-mediatek-tell-GDMA-when-we-are-turning-.patch |  43 ++++
 .../0046-net-mediatek-add-irq-delay.patch          |  21 ++
 .../0051-net-mediatek-increase-tx_timeout.patch    |  21 ++
 .../ramips/patches-4.14/0062-mdio-atomic.patch     |  14 ++
 .../ramips/patches-4.14/0063-atomic-sleep.patch    |  46 ++++
 ...k-remove-superfluous-pin-setup-for-MT7622.patch | 102 ++++++++
 12 files changed, 771 insertions(+)
 create mode 100644 target/linux/ramips/patches-4.14/0027-net-next-mediatek-fix-DQL-support.patch
 create mode 100644 target/linux/ramips/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch
 create mode 100644 target/linux/ramips/patches-4.14/0033-dsa-multi-cpu.patch
 create mode 100644 target/linux/ramips/patches-4.14/0035-net-mediatek-disable-RX-VLan-offloading.patch
 create mode 100644 target/linux/ramips/patches-4.14/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch
 create mode 100644 target/linux/ramips/patches-4.14/0043-net-next-mediatek-enable-special-tag-indication-for-.patch
 create mode 100644 target/linux/ramips/patches-4.14/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch
 create mode 100644 target/linux/ramips/patches-4.14/0046-net-mediatek-add-irq-delay.patch
 create mode 100644 target/linux/ramips/patches-4.14/0051-net-mediatek-increase-tx_timeout.patch
 create mode 100644 target/linux/ramips/patches-4.14/0062-mdio-atomic.patch
 create mode 100644 target/linux/ramips/patches-4.14/0063-atomic-sleep.patch
 create mode 100644 target/linux/ramips/patches-4.14/0175-net-mediatek-remove-superfluous-pin-setup-for-MT7622.patch
diff mbox series

Patch

diff --git a/target/linux/ramips/patches-4.14/0027-net-next-mediatek-fix-DQL-support.patch b/target/linux/ramips/patches-4.14/0027-net-next-mediatek-fix-DQL-support.patch
new file mode 100644
index 000000000000..3ea2f456a8ce
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0027-net-next-mediatek-fix-DQL-support.patch
@@ -0,0 +1,92 @@ 
+From f974e397b806f7b16d11cc1542538616291924f1 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Sat, 23 Apr 2016 11:57:21 +0200
+Subject: [PATCH 27/57] net-next: mediatek: fix DQL support
+
+The MTK ethernet core has 2 MACs both sitting on the same DMA ring. The
+current code will assign the TX traffic of each MAC to its own DQL. This
+results in the amount of data, that DQL says is in the queue incorrect. As
+the data from multiple devices is infact enqueued. This makes any decision
+based on these value non deterministic. Fix this by tracking all TX
+traffic, regardless of the MAC it belongs to in the DQL of all devices
+using the DMA.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 +++++++++++++++++------------
+ 1 file changed, 21 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -779,7 +779,16 @@ static int mtk_tx_map(struct sk_buff *sk
+ 	WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
+ 				(!nr_frags * TX_DMA_LS0)));
+ 
+-	netdev_sent_queue(dev, skb->len);
++	/* we have a single DMA ring so BQL needs to be updated for all devices
++	 * sitting on this ring
++	 */
++	for (i = 0; i < MTK_MAC_COUNT; i++) {
++		if (!eth->netdev[i])
++			continue;
++
++		netdev_sent_queue(eth->netdev[i], skb->len);
++	}
++
+ 	skb_tx_timestamp(skb);
+ 
+ 	ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
+@@ -1076,20 +1085,17 @@ static int mtk_poll_tx(struct mtk_eth *e
+ 	struct mtk_tx_dma *desc;
+ 	struct sk_buff *skb;
+ 	struct mtk_tx_buf *tx_buf;
+-	unsigned int done[MTK_MAX_DEVS];
+-	unsigned int bytes[MTK_MAX_DEVS];
++	int total = 0, done = 0;
++	unsigned int bytes = 0;
+ 	u32 cpu, dma;
+-	int total = 0, i;
+-
+-	memset(done, 0, sizeof(done));
+-	memset(bytes, 0, sizeof(bytes));
++	int i;
+ 
+ 	cpu = mtk_r32(eth, MTK_QTX_CRX_PTR);
+ 	dma = mtk_r32(eth, MTK_QTX_DRX_PTR);
+ 
+ 	desc = mtk_qdma_phys_to_virt(ring, cpu);
+ 
+-	while ((cpu != dma) && budget) {
++	while ((cpu != dma) && (done < budget)) {
+ 		u32 next_cpu = desc->txd2;
+ 		int mac = 0;
+ 
+@@ -1106,9 +1112,8 @@ static int mtk_poll_tx(struct mtk_eth *e
+ 			break;
+ 
+ 		if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) {
+-			bytes[mac] += skb->len;
+-			done[mac]++;
+-			budget--;
++			bytes += skb->len;
++			done++;
+ 		}
+ 		mtk_tx_unmap(eth, tx_buf);
+ 
+@@ -1120,11 +1125,13 @@ static int mtk_poll_tx(struct mtk_eth *e
+ 
+ 	mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
+ 
++	/* we have a single DMA ring so BQL needs to be updated for all devices
++	 * sitting on this ring
++	 */
+ 	for (i = 0; i < MTK_MAC_COUNT; i++) {
+-		if (!eth->netdev[i] || !done[i])
++		if (!eth->netdev[i])
+ 			continue;
+-		netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
+-		total += done[i];
++		netdev_completed_queue(eth->netdev[i], done, bytes);
+ 	}
+ 
+ 	if (mtk_queue_stopped(eth) &&
diff --git a/target/linux/ramips/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch b/target/linux/ramips/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch
new file mode 100644
index 000000000000..c01703d07b8b
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch
@@ -0,0 +1,26 @@ 
+From 52e9ce30a2b3c414e0efb20632fefa7cfc5096e6 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 10 Aug 2017 14:44:18 +0200
+Subject: [PATCH 32/57] net: dsa: mediatek: add support for GMAC2 wired to ext
+ phy
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/dsa/mt7530.c                    | 5 +++++
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -991,6 +991,11 @@ mt7530_setup(struct dsa_switch *ds)
+ 	val = mt7530_read(priv, MT7530_MHWTRAP);
+ 	val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
+ 	val |= MHWTRAP_MANUAL;
++	if (!dsa_is_cpu_port(ds, 5)) {
++		val |= MHWTRAP_P5_DIS;
++		val |= MHWTRAP_P5_MAC_SEL;
++		val |= MHWTRAP_P5_RGMII_MODE;
++	}
+ 	mt7530_write(priv, MT7530_MHWTRAP, val);
+ 
+ 	/* Enable and reset MIB counters */
diff --git a/target/linux/ramips/patches-4.14/0033-dsa-multi-cpu.patch b/target/linux/ramips/patches-4.14/0033-dsa-multi-cpu.patch
new file mode 100644
index 000000000000..926e0d842169
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0033-dsa-multi-cpu.patch
@@ -0,0 +1,268 @@ 
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -670,6 +670,9 @@ static int
+ mt7530_cpu_port_enable(struct mt7530_priv *priv,
+ 		       int port)
+ {
++	u8 port_mask = 0;
++	int i;
++
+ 	/* Enable Mediatek header mode on the cpu port */
+ 	mt7530_write(priv, MT7530_PVC_P(port),
+ 		     PORT_SPEC_TAG);
+@@ -686,8 +689,12 @@ mt7530_cpu_port_enable(struct mt7530_pri
+ 	/* CPU port gets connected to all user ports of
+ 	 * the switch
+ 	 */
++	for (i = 0; i < MT7530_NUM_PORTS; i++)
++		if ((priv->ds->enabled_port_mask & BIT(i)) &&
++		    (dsa_port_upstream_port(priv->ds, i) == port))
++			port_mask |= BIT(i);
+ 	mt7530_write(priv, MT7530_PCR_P(port),
+-		     PCR_MATRIX(priv->ds->enabled_port_mask));
++		     PCR_MATRIX(port_mask));
+ 
+ 	return 0;
+ }
+@@ -697,6 +704,7 @@ mt7530_port_enable(struct dsa_switch *ds
+ 		   struct phy_device *phy)
+ {
+ 	struct mt7530_priv *priv = ds->priv;
++	u8 upstream = dsa_port_upstream_port(ds, port);
+ 
+ 	mutex_lock(&priv->reg_mutex);
+ 
+@@ -707,7 +715,7 @@ mt7530_port_enable(struct dsa_switch *ds
+ 	 * restore the port matrix if the port is the member of a certain
+ 	 * bridge.
+ 	 */
+-	priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT));
++	priv->ports[port].pm |= PCR_MATRIX(BIT(upstream));
+ 	priv->ports[port].enable = true;
+ 	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
+ 		   priv->ports[port].pm);
+@@ -770,7 +778,8 @@ mt7530_port_bridge_join(struct dsa_switc
+ 			struct net_device *bridge)
+ {
+ 	struct mt7530_priv *priv = ds->priv;
+-	u32 port_bitmap = BIT(MT7530_CPU_PORT);
++	u8 upstream = dsa_port_upstream_port(ds, port);
++	u32 port_bitmap = BIT(upstream);
+ 	int i;
+ 
+ 	mutex_lock(&priv->reg_mutex);
+@@ -808,6 +817,7 @@ mt7530_port_bridge_leave(struct dsa_swit
+ 			 struct net_device *bridge)
+ {
+ 	struct mt7530_priv *priv = ds->priv;
++	u8 upstream = dsa_port_upstream_port(ds, port);
+ 	int i;
+ 
+ 	mutex_lock(&priv->reg_mutex);
+@@ -832,8 +842,8 @@ mt7530_port_bridge_leave(struct dsa_swit
+ 	 */
+ 	if (priv->ports[port].enable)
+ 		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
+-			   PCR_MATRIX(BIT(MT7530_CPU_PORT)));
+-	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
++			   PCR_MATRIX(BIT(upstream)));
++	priv->ports[port].pm = PCR_MATRIX(BIT(upstream));
+ 
+ 	mutex_unlock(&priv->reg_mutex);
+ }
+@@ -908,15 +918,7 @@ err:
+ static enum dsa_tag_protocol
+ mtk_get_tag_protocol(struct dsa_switch *ds)
+ {
+-	struct mt7530_priv *priv = ds->priv;
+-
+-	if (!dsa_is_cpu_port(ds, MT7530_CPU_PORT)) {
+-		dev_warn(priv->dev,
+-			 "port not matched with tagging CPU port\n");
+-		return DSA_TAG_PROTO_NONE;
+-	} else {
+-		return DSA_TAG_PROTO_MTK;
+-	}
++	return DSA_TAG_PROTO_MTK;
+ }
+ 
+ static int
+@@ -989,7 +991,7 @@ mt7530_setup(struct dsa_switch *ds)
+ 
+ 	/* Enable Port 6 only; P5 as GMAC5 which currently is not supported */
+ 	val = mt7530_read(priv, MT7530_MHWTRAP);
+-	val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
++	val &= ~MHWTRAP_P5_DIS & ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
+ 	val |= MHWTRAP_MANUAL;
+ 	if (!dsa_is_cpu_port(ds, 5)) {
+ 		val |= MHWTRAP_P5_DIS;
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -185,6 +185,10 @@ struct dsa_port {
+ 	u8			stp_state;
+ 	struct net_device	*bridge_dev;
+ 	struct devlink_port	devlink_port;
++
++	struct net_device	*ethernet;
++	int			upstream;
++
+ 	/*
+ 	 * Original copy of the master netdev ethtool_ops
+ 	 */
+@@ -266,6 +270,11 @@ static inline bool dsa_is_normal_port(st
+ 	return !dsa_is_cpu_port(ds, p) && !dsa_is_dsa_port(ds, p);
+ }
+ 
++static inline bool dsa_is_upstream_port(struct dsa_switch *ds, int p)
++{
++	return dsa_is_cpu_port(ds, p) || dsa_is_dsa_port(ds, p);
++}
++
+ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
+ {
+ 	struct dsa_switch_tree *dst = ds->dst;
+@@ -282,6 +291,18 @@ static inline u8 dsa_upstream_port(struc
+ 		return ds->rtable[dst->cpu_dp->ds->index];
+ }
+ 
++static inline u8 dsa_port_upstream_port(struct dsa_switch *ds, int port)
++{
++	/*
++	 * If this port has a specific upstream cpu port, use it,
++	 * otherwise use the switch default.
++	 */
++	if (ds->ports[port].upstream)
++		return ds->ports[port].upstream;
++	else
++		return dsa_upstream_port(ds);
++}
++
+ typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
+ 			      bool is_static, void *data);
+ struct dsa_switch_ops {
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -253,6 +253,8 @@ static int dsa_cpu_port_apply(struct dsa
+ 	memset(&port->devlink_port, 0, sizeof(port->devlink_port));
+ 	err = devlink_port_register(ds->devlink, &port->devlink_port,
+ 				    port->index);
++	if (port->netdev)
++		port->netdev->dsa_ptr = ds->dst;
+ 	return err;
+ }
+ 
+@@ -262,6 +264,12 @@ static void dsa_cpu_port_unapply(struct
+ 	dsa_cpu_dsa_destroy(port);
+ 	port->ds->cpu_port_mask &= ~BIT(port->index);
+ 
++	if (port->netdev)
++		port->netdev->dsa_ptr = NULL;
++	if (port->ethernet) {
++		dev_put(port->ethernet);
++		port->ethernet = NULL;
++	}
+ }
+ 
+ static int dsa_user_port_apply(struct dsa_port *port)
+@@ -505,10 +513,9 @@ static int dsa_cpu_parse(struct dsa_port
+ 		dev_put(ethernet_dev);
+ 	}
+ 
+-	if (!dst->cpu_dp) {
++	if (!dst->cpu_dp)
+ 		dst->cpu_dp = port;
+-		dst->cpu_dp->netdev = ethernet_dev;
+-	}
++	port->netdev = ethernet_dev;
+ 
+ 	/* Initialize cpu_port_mask now for drv->setup()
+ 	 * to have access to a correct value, just like what
+@@ -526,6 +533,29 @@ static int dsa_cpu_parse(struct dsa_port
+ 
+ 	dst->rcv = dst->tag_ops->rcv;
+ 
++	dev_hold(ethernet_dev);
++	ds->ports[index].ethernet = ethernet_dev;
++	ds->cpu_port_mask |= BIT(index);
++
++	return 0;
++}
++
++static int dsa_user_parse(struct dsa_port *port, u32 index,
++			  struct dsa_switch *ds)
++{
++	struct device_node *cpu_port;
++	const unsigned int *cpu_port_reg;
++	int cpu_port_index;
++
++	cpu_port = of_parse_phandle(port->dn, "cpu", 0);
++	if (cpu_port) {
++		cpu_port_reg = of_get_property(cpu_port, "reg", NULL);
++		if (!cpu_port_reg)
++			return -EINVAL;
++		cpu_port_index = be32_to_cpup(cpu_port_reg);
++		ds->ports[index].upstream = cpu_port_index;
++	}
++
+ 	return 0;
+ }
+ 
+@@ -533,7 +563,7 @@ static int dsa_ds_parse(struct dsa_switc
+ {
+ 	struct dsa_port *port;
+ 	u32 index;
+-	int err;
++	int err = 0;
+ 
+ 	for (index = 0; index < ds->num_ports; index++) {
+ 		port = &ds->ports[index];
+@@ -546,6 +576,9 @@ static int dsa_ds_parse(struct dsa_switc
+ 			if (err)
+ 				return err;
+ 		} else {
++			err = dsa_user_parse(port, index, ds);
++			if (err)
++				return err;
+ 			/* Initialize enabled_port_mask now for drv->setup()
+ 			 * to have access to a correct value, just like what
+ 			 * net/dsa/dsa.c::dsa_switch_setup_one does.
+--- a/net/dsa/dsa_priv.h
++++ b/net/dsa/dsa_priv.h
+@@ -91,6 +91,8 @@ struct dsa_slave_priv {
+ 
+ 	/* TC context */
+ 	struct list_head	mall_tc_list;
++
++	struct net_device       *master;
+ };
+ 
+ /* dsa.c */
+@@ -177,6 +179,9 @@ extern const struct dsa_device_ops trail
+ 
+ static inline struct net_device *dsa_master_netdev(struct dsa_slave_priv *p)
+ {
++	if (p->master)
++		return p->master;
++
+ 	return p->dp->cpu_dp->netdev;
+ }
+ 
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -1263,7 +1263,7 @@ int dsa_slave_create(struct dsa_port *po
+ 	int ret;
+ 
+ 	cpu_dp = ds->dst->cpu_dp;
+-	master = cpu_dp->netdev;
++	master = ds->ports[port->upstream].ethernet;
+ 
+ 	if (!ds->num_tx_queues)
+ 		ds->num_tx_queues = 1;
+@@ -1301,6 +1301,7 @@ int dsa_slave_create(struct dsa_port *po
+ 	p->dp = port;
+ 	INIT_LIST_HEAD(&p->mall_tc_list);
+ 	p->xmit = dst->tag_ops->xmit;
++	p->master = master;
+ 
+ 	p->old_pause = -1;
+ 	p->old_link = -1;
diff --git a/target/linux/ramips/patches-4.14/0035-net-mediatek-disable-RX-VLan-offloading.patch b/target/linux/ramips/patches-4.14/0035-net-mediatek-disable-RX-VLan-offloading.patch
new file mode 100644
index 000000000000..72a2ece464bc
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0035-net-mediatek-disable-RX-VLan-offloading.patch
@@ -0,0 +1,47 @@ 
+From 35b83b85e752a6660b92f08c0fb912308f25cf6d Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 10 Aug 2017 15:56:40 +0200
+Subject: [PATCH 35/57] net: mediatek: disable RX VLan offloading
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 9 ++++++---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 --
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -709,8 +709,8 @@ static int mtk_tx_map(struct sk_buff *sk
+ 		txd4 |= TX_DMA_CHKSUM;
+ 
+ 	/* VLAN header offload */
+-	if (skb_vlan_tag_present(skb))
+-		txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb);
++//	if (skb_vlan_tag_present(skb))
++//		txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb);
+ 
+ 	mapped_addr = dma_map_single(eth->dev, skb->data,
+ 				     skb_headlen(skb), DMA_TO_DEVICE);
+@@ -1980,7 +1980,10 @@ static int mtk_hw_init(struct mtk_eth *e
+ 	mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
+ 
+ 	/* Enable RX VLan Offloading */
+-	mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
++	if (MTK_HW_FEATURES & NETIF_F_HW_VLAN_CTAG_RX)
++		mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
++	else
++		mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
+ 
+ 	/* enable interrupt delay for RX */
+ 	mtk_w32(eth, MTK_PDMA_DELAY_RX_DELAY, MTK_PDMA_DELAY_INT);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -34,8 +34,6 @@
+ 				 NETIF_MSG_TX_ERR)
+ #define MTK_HW_FEATURES		(NETIF_F_IP_CSUM | \
+ 				 NETIF_F_RXCSUM | \
+-				 NETIF_F_HW_VLAN_CTAG_TX | \
+-				 NETIF_F_HW_VLAN_CTAG_RX | \
+ 				 NETIF_F_SG | NETIF_F_TSO | \
+ 				 NETIF_F_TSO6 | \
+ 				 NETIF_F_IPV6_CSUM)
diff --git a/target/linux/ramips/patches-4.14/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch b/target/linux/ramips/patches-4.14/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch
new file mode 100644
index 000000000000..8163e4475d57
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch
@@ -0,0 +1,50 @@ 
+From a306af3b97c56b9e224a2f9ee04838a2d32ff60b Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Wed, 9 Aug 2017 14:44:07 +0200
+Subject: [PATCH 42/57] net-next: mediatek: honour special tag bit inside RX
+ DMA descriptor
+
+For HW NAT/QoS to work the DSA driver needs to turn the special tag bit
+inside the ingress control register on. This has the side effect that
+the code working out which ingress gmac we have breaks. Fix this by
+honouring the special tag bit inside the RX free descriptor.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 14 ++++++++++----
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 +
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -999,10 +999,16 @@ static int mtk_poll_rx(struct napi_struc
+ 		if (!(trxd.rxd2 & RX_DMA_DONE))
+ 			break;
+ 
+-		/* find out which mac the packet come from. values start at 1 */
+-		mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
+-		      RX_DMA_FPORT_MASK;
+-		mac--;
++		/* find out which mac the packet comes from. If the special tag is
++		 * we can assume that the traffic is coming from the builtin mt7530
++		 * and the DSA driver has loaded. FPORT will be the physical switch
++		 * port in this case rather than the FE forward port id. */
++		if (!(trxd.rxd4 & RX_DMA_SP_TAG)) {
++			/* values start at 1 */
++			mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
++			      RX_DMA_FPORT_MASK;
++			mac--;
++		}
+ 
+ 		if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
+ 			     !eth->netdev[mac]))
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -287,6 +287,7 @@
+ 
+ /* QDMA descriptor rxd4 */
+ #define RX_DMA_L4_VALID		BIT(24)
++#define RX_DMA_SP_TAG		BIT(22)
+ #define RX_DMA_FPORT_SHIFT	19
+ #define RX_DMA_FPORT_MASK	0x7
+ 
diff --git a/target/linux/ramips/patches-4.14/0043-net-next-mediatek-enable-special-tag-indication-for-.patch b/target/linux/ramips/patches-4.14/0043-net-next-mediatek-enable-special-tag-indication-for-.patch
new file mode 100644
index 000000000000..a658a572fc22
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0043-net-next-mediatek-enable-special-tag-indication-for-.patch
@@ -0,0 +1,41 @@ 
+From 53e3d9af39805a7e1ba81a047a9ab433be0e82f5 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Wed, 9 Aug 2017 14:56:53 +0200
+Subject: [PATCH 43/57] net-next: mediatek: enable special tag indication for
+ PDMA
+
+The Ingress special tag indication was only enabled for QDMA and not PDMA.
+Properly initialize the STAG bit. This broke HW NAT and Qos from working
+for traffic coming in via a DSA device. The PPE failed to properly parse
+the traffic as it was not expecting the special tag.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1984,6 +1984,8 @@ static int mtk_hw_init(struct mtk_eth *e
+ 	 */
+ 	val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
+ 	mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
++	val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
++	mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
+ 
+ 	/* Enable RX VLan Offloading */
+ 	if (MTK_HW_FEATURES & NETIF_F_HW_VLAN_CTAG_RX)
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -72,6 +72,10 @@
+ #define MTK_CDMQ_IG_CTRL	0x1400
+ #define MTK_CDMQ_STAG_EN	BIT(0)
+ 
++/* CDMP Ingress Control Register */
++#define MTK_CDMP_IG_CTRL	0x400
++#define MTK_CDMP_STAG_EN	BIT(0)
++
+ /* CDMP Exgress Control Register */
+ #define MTK_CDMP_EG_CTRL	0x404
+ 
diff --git a/target/linux/ramips/patches-4.14/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch b/target/linux/ramips/patches-4.14/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch
new file mode 100644
index 000000000000..4a69e7aadf48
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch
@@ -0,0 +1,43 @@ 
+From 6a5932028a4f3217ed7c9d602f269611d95dd8ca Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Wed, 9 Aug 2017 15:13:19 +0200
+Subject: [PATCH 44/57] net-next: dsa: mediatek: tell GDMA when we are turning
+ on the special tag
+
+Enabling this bit will make the RX DMA descriptor enable the SP bit for all
+ingress traffic inside the return descriptor. The PPE needs this to know
+that a SP is present.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/dsa/mt7530.c | 5 +++++
+ drivers/net/dsa/mt7530.h | 4 ++++
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -677,6 +677,11 @@ mt7530_cpu_port_enable(struct mt7530_pri
+ 	mt7530_write(priv, MT7530_PVC_P(port),
+ 		     PORT_SPEC_TAG);
+ 
++	/* Enable Mediatek header mode on the GMAC that the cpu port
++	 * connects to */
++	regmap_write_bits(priv->ethernet, MTK_GDMA_FWD_CFG(port),
++			  GDMA_SPEC_TAG, GDMA_SPEC_TAG);
++
+ 	/* Setup the MAC by default for the cpu port */
+ 	mt7530_write(priv, MT7530_PMCR_P(port), PMCR_CPUP_LINK);
+ 
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -22,6 +22,10 @@
+ 
+ #define TRGMII_BASE(x)			(0x10000 + (x))
+ 
++/* Registers for GDMA configuration access */
++#define MTK_GDMA_FWD_CFG(x)		(0x500 + (x * 0x1000))
++#define GDMA_SPEC_TAG			BIT(24)
++
+ /* Registers to ethsys access */
+ #define ETHSYS_CLKCFG0			0x2c
+ #define  ETHSYS_TRGMII_CLK_SEL362_5	BIT(11)
diff --git a/target/linux/ramips/patches-4.14/0046-net-mediatek-add-irq-delay.patch b/target/linux/ramips/patches-4.14/0046-net-mediatek-add-irq-delay.patch
new file mode 100644
index 000000000000..3ace7265c6ca
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0046-net-mediatek-add-irq-delay.patch
@@ -0,0 +1,21 @@ 
+From 6e081074df96bf3762c2e6438c383f11a56b0a7e Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 10 Aug 2017 15:58:04 +0200
+Subject: [PATCH 46/57] net: mediatek: add irq delay
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 ++++++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++++-
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1995,6 +1995,7 @@ static int mtk_hw_init(struct mtk_eth *e
+ 
+ 	/* enable interrupt delay for RX */
+ 	mtk_w32(eth, MTK_PDMA_DELAY_RX_DELAY, MTK_PDMA_DELAY_INT);
++	//mtk_w32(eth, MTK_PDMA_DELAY_RX_DELAY, MTK_QDMA_DELAY_INT);
+ 
+ 	/* disable delay and normal interrupt */
+ 	mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
diff --git a/target/linux/ramips/patches-4.14/0051-net-mediatek-increase-tx_timeout.patch b/target/linux/ramips/patches-4.14/0051-net-mediatek-increase-tx_timeout.patch
new file mode 100644
index 000000000000..f4c0fce56686
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0051-net-mediatek-increase-tx_timeout.patch
@@ -0,0 +1,21 @@ 
+From 5cbf53c7e5eac5bacc409461888789accdaf8eec Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 10 Aug 2017 16:00:06 +0200
+Subject: [PATCH 51/57] net: mediatek: increase tx_timeout
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2454,7 +2454,7 @@ static int mtk_add_mac(struct mtk_eth *e
+ 	mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
+ 
+ 	SET_NETDEV_DEV(eth->netdev[id], eth->dev);
+-	eth->netdev[id]->watchdog_timeo = 5 * HZ;
++	eth->netdev[id]->watchdog_timeo = 30 * HZ;
+ 	eth->netdev[id]->netdev_ops = &mtk_netdev_ops;
+ 	eth->netdev[id]->base_addr = (unsigned long)eth->base;
+ 
diff --git a/target/linux/ramips/patches-4.14/0062-mdio-atomic.patch b/target/linux/ramips/patches-4.14/0062-mdio-atomic.patch
new file mode 100644
index 000000000000..9ce66ef48736
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0062-mdio-atomic.patch
@@ -0,0 +1,14 @@ 
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -76,7 +76,10 @@ static int mtk_mdio_busy_wait(struct mtk
+ 			return 0;
+ 		if (time_after(jiffies, t_start + PHY_IAC_TIMEOUT))
+ 			break;
+-		usleep_range(10, 20);
++		if (in_atomic())
++			udelay(10);
++		else
++			usleep_range(10, 20);
+ 	}
+ 
+ 	dev_err(eth->dev, "mdio: MDIO timeout\n");
diff --git a/target/linux/ramips/patches-4.14/0063-atomic-sleep.patch b/target/linux/ramips/patches-4.14/0063-atomic-sleep.patch
new file mode 100644
index 000000000000..0dde3fdb6440
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0063-atomic-sleep.patch
@@ -0,0 +1,46 @@ 
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -409,6 +409,7 @@ static int mtk_mdio_init(struct mtk_eth
+ 
+ 	snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name);
+ 	ret = of_mdiobus_register(eth->mii_bus, mii_np);
++printk("%s:%s[%d]%d %p\n", __FILE__, __func__, __LINE__, ret, eth->mii_bus);
+ 
+ err_put_node:
+ 	of_node_put(mii_np);
+@@ -1472,7 +1473,10 @@ static void mtk_hwlro_rx_uninit(struct m
+ 	for (i = 0; i < 10; i++) {
+ 		val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0);
+ 		if (val & MTK_LRO_RING_RELINQUISH_DONE) {
+-			msleep(20);
++			if (in_atomic())
++				mdelay(20);
++			else
++				msleep(20);
+ 			continue;
+ 		}
+ 		break;
+@@ -1868,7 +1872,10 @@ static void mtk_stop_dma(struct mtk_eth
+ 	for (i = 0; i < 10; i++) {
+ 		val = mtk_r32(eth, glo_cfg);
+ 		if (val & (MTK_TX_DMA_BUSY | MTK_RX_DMA_BUSY)) {
+-			msleep(20);
++			if (in_atomic())
++				mdelay(20);
++			else
++				msleep(20);
+ 			continue;
+ 		}
+ 		break;
+@@ -1906,7 +1913,10 @@ static void ethsys_reset(struct mtk_eth
+ 			   reset_bits,
+ 			   reset_bits);
+ 
+-	usleep_range(1000, 1100);
++	if (in_atomic())
++		udelay(1000);
++	else
++		usleep_range(1000, 1100);
+ 	regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL,
+ 			   reset_bits,
+ 			   ~reset_bits);
diff --git a/target/linux/ramips/patches-4.14/0175-net-mediatek-remove-superfluous-pin-setup-for-MT7622.patch b/target/linux/ramips/patches-4.14/0175-net-mediatek-remove-superfluous-pin-setup-for-MT7622.patch
new file mode 100644
index 000000000000..86354973b146
--- /dev/null
+++ b/target/linux/ramips/patches-4.14/0175-net-mediatek-remove-superfluous-pin-setup-for-MT7622.patch
@@ -0,0 +1,102 @@ 
+From d96cf7e724105dc73f623c2019ab5bc78cef036e Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 20 Dec 2017 17:47:06 +0800
+Subject: [PATCH 175/224] net: mediatek: remove superfluous pin setup for
+ MT7622 SoC
+
+Remove superfluous pin setup to get out of accessing invalid I/O pin
+registers because the way for pin configuring tends to be different from
+various SoCs and thus it should be better being managed and controlled by
+the pinctrl driver which MT7622 already can support.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 +++++++++++++++++------------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 +++
+ 2 files changed, 24 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1976,14 +1976,16 @@ static int mtk_hw_init(struct mtk_eth *e
+ 	}
+ 	regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
+ 
+-	/* Set GE2 driving and slew rate */
+-	regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00);
++	if (eth->pctl) {
++		/* Set GE2 driving and slew rate */
++		regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00);
+ 
+-	/* set GE2 TDSEL */
+-	regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5);
++		/* set GE2 TDSEL */
++		regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5);
+ 
+-	/* set GE2 TUNE */
+-	regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0);
++		/* set GE2 TUNE */
++		regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0);
++	}
+ 
+ 	/* Set linkdown as the default for each GMAC. Its own MCR would be set
+ 	 * up with the more appropriate value when mtk_phy_link_adjust call is
+@@ -2568,11 +2570,13 @@ static int mtk_probe(struct platform_dev
+ 		}
+ 	}
+ 
+-	eth->pctl = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+-						    "mediatek,pctl");
+-	if (IS_ERR(eth->pctl)) {
+-		dev_err(&pdev->dev, "no pctl regmap found\n");
+-		return PTR_ERR(eth->pctl);
++	if (eth->soc->required_pctl) {
++		eth->pctl = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
++							    "mediatek,pctl");
++		if (IS_ERR(eth->pctl)) {
++			dev_err(&pdev->dev, "no pctl regmap found\n");
++			return PTR_ERR(eth->pctl);
++		}
+ 	}
+ 
+ 	for (i = 0; i < 3; i++) {
+@@ -2698,17 +2702,20 @@ static int mtk_remove(struct platform_de
+ 
+ static const struct mtk_soc_data mt2701_data = {
+ 	.caps = MTK_GMAC1_TRGMII,
+-	.required_clks = MT7623_CLKS_BITMAP
++	.required_clks = MT7623_CLKS_BITMAP,
++	.required_pctl = true,
+ };
+ 
+ static const struct mtk_soc_data mt7622_data = {
+ 	.caps = MTK_DUAL_GMAC_SHARED_SGMII | MTK_GMAC1_ESW,
+-	.required_clks = MT7622_CLKS_BITMAP
++	.required_clks = MT7622_CLKS_BITMAP,
++	.required_pctl = false,
+ };
+ 
+ static const struct mtk_soc_data mt7623_data = {
+ 	.caps = MTK_GMAC1_TRGMII,
+-	.required_clks = MT7623_CLKS_BITMAP
++	.required_clks = MT7623_CLKS_BITMAP,
++	.required_pctl = true,
+ };
+ 
+ const struct of_device_id of_mtk_match[] = {
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -574,10 +574,13 @@ struct mtk_rx_ring {
+  * @caps			Flags shown the extra capability for the SoC
+  * @required_clks		Flags shown the bitmap for required clocks on
+  *				the target SoC
++ * @required_pctl		A bool value to show whether the SoC requires
++ *				the extra setup for those pins used by GMAC.
+  */
+ struct mtk_soc_data {
+ 	u32		caps;
+ 	u32		required_clks;
++	bool		required_pctl;
+ };
+ 
+ /* currently no SoC has more than 2 macs */