aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-4.14
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mediatek/patches-4.14')
-rw-r--r--target/linux/mediatek/patches-4.14/0006-reset-mediatek-mt2701-reset-driver.patch29
-rw-r--r--target/linux/mediatek/patches-4.14/0012-clk-dont-disable-unused-clocks.patch21
-rw-r--r--target/linux/mediatek/patches-4.14/0027-net-next-mediatek-fix-DQL-support.patch94
-rw-r--r--target/linux/mediatek/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch28
-rw-r--r--target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch278
-rw-r--r--target/linux/mediatek/patches-4.14/0035-net-mediatek-disable-RX-VLan-offloading.patch47
-rw-r--r--target/linux/mediatek/patches-4.14/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch50
-rw-r--r--target/linux/mediatek/patches-4.14/0043-net-next-mediatek-enable-special-tag-indication-for-.patch41
-rw-r--r--target/linux/mediatek/patches-4.14/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch43
-rw-r--r--target/linux/mediatek/patches-4.14/0045-net-dsa-mediatek-turn-into-platform-driver.patch81
-rw-r--r--target/linux/mediatek/patches-4.14/0046-net-mediatek-add-irq-delay.patch23
-rw-r--r--target/linux/mediatek/patches-4.14/0048-net-core-add-RPS-balancer.patch90
-rw-r--r--target/linux/mediatek/patches-4.14/0051-net-mediatek-increase-tx_timeout.patch21
-rw-r--r--target/linux/mediatek/patches-4.14/0052-net-phy-add-FC.patch21
-rw-r--r--target/linux/mediatek/patches-4.14/0062-mdio-atomic.patch14
-rw-r--r--target/linux/mediatek/patches-4.14/0063-atomic-sleep.patch48
-rw-r--r--target/linux/mediatek/patches-4.14/0064-dts.patch597
17 files changed, 1526 insertions, 0 deletions
diff --git a/target/linux/mediatek/patches-4.14/0006-reset-mediatek-mt2701-reset-driver.patch b/target/linux/mediatek/patches-4.14/0006-reset-mediatek-mt2701-reset-driver.patch
new file mode 100644
index 0000000000..770a1a0d76
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0006-reset-mediatek-mt2701-reset-driver.patch
@@ -0,0 +1,29 @@
+From 596c3a7300c0419dba71d58cbd4136e0d1e12a4e Mon Sep 17 00:00:00 2001
+From: Shunli Wang <shunli.wang@mediatek.com>
+Date: Tue, 5 Jan 2016 14:30:22 +0800
+Subject: [PATCH 06/57] reset: mediatek: mt2701 reset driver
+
+In infrasys and perifsys, there are many reset
+control bits for kinds of modules. These bits are
+used as actual reset controllers to be registered
+into kernel's generic reset controller framework.
+
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
+---
+ drivers/clk/mediatek/clk-mt2701.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+Index: linux-4.14.11/drivers/clk/mediatek/clk-mt2701.c
+===================================================================
+--- linux-4.14.11.orig/drivers/clk/mediatek/clk-mt2701.c
++++ linux-4.14.11/drivers/clk/mediatek/clk-mt2701.c
+@@ -771,6 +771,8 @@ static void mtk_infrasys_init_early(stru
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
++
++ mtk_register_reset_controller(node, 2, 0x30);
+ }
+ CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt2701-infracfg",
+ mtk_infrasys_init_early);
diff --git a/target/linux/mediatek/patches-4.14/0012-clk-dont-disable-unused-clocks.patch b/target/linux/mediatek/patches-4.14/0012-clk-dont-disable-unused-clocks.patch
new file mode 100644
index 0000000000..ed4111dce3
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0012-clk-dont-disable-unused-clocks.patch
@@ -0,0 +1,21 @@
+From 0e60d2112968ccb2570535bf19fb5020c9b28c08 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 7 Apr 2016 07:18:35 +0200
+Subject: [PATCH 12/57] clk: dont disable unused clocks
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/clk/clk.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -796,7 +796,7 @@ unlock_out:
+ clk_core_disable_unprepare(core->parent);
+ }
+
+-static bool clk_ignore_unused;
++static bool clk_ignore_unused = true;
+ static int __init clk_ignore_unused_setup(char *__unused)
+ {
+ clk_ignore_unused = true;
diff --git a/target/linux/mediatek/patches-4.14/0027-net-next-mediatek-fix-DQL-support.patch b/target/linux/mediatek/patches-4.14/0027-net-next-mediatek-fix-DQL-support.patch
new file mode 100644
index 0000000000..3431b119c0
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0027-net-next-mediatek-fix-DQL-support.patch
@@ -0,0 +1,94 @@
+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(-)
+
+Index: linux-4.14.11/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+===================================================================
+--- linux-4.14.11.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ linux-4.14.11/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/mediatek/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch b/target/linux/mediatek/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch
new file mode 100644
index 0000000000..073934d6e1
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch
@@ -0,0 +1,28 @@
+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(+)
+
+Index: linux-4.14.11/drivers/net/dsa/mt7530.c
+===================================================================
+--- linux-4.14.11.orig/drivers/net/dsa/mt7530.c
++++ linux-4.14.11/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/mediatek/patches-4.14/0033-dsa-multi-cpu.patch b/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch
new file mode 100644
index 0000000000..92f4c98dca
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch
@@ -0,0 +1,278 @@
+Index: linux-4.14.14/drivers/net/dsa/mt7530.c
+===================================================================
+--- linux-4.14.14.orig/drivers/net/dsa/mt7530.c
++++ linux-4.14.14/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;
+Index: linux-4.14.14/include/net/dsa.h
+===================================================================
+--- linux-4.14.14.orig/include/net/dsa.h
++++ linux-4.14.14/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 {
+Index: linux-4.14.14/net/dsa/dsa2.c
+===================================================================
+--- linux-4.14.14.orig/net/dsa/dsa2.c
++++ linux-4.14.14/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.
+Index: linux-4.14.14/net/dsa/dsa_priv.h
+===================================================================
+--- linux-4.14.14.orig/net/dsa/dsa_priv.h
++++ linux-4.14.14/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;
+ }
+
+Index: linux-4.14.14/net/dsa/slave.c
+===================================================================
+--- linux-4.14.14.orig/net/dsa/slave.c
++++ linux-4.14.14/net/dsa/slave.c
+@@ -1257,7 +1257,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;
+@@ -1295,6 +1295,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/mediatek/patches-4.14/0035-net-mediatek-disable-RX-VLan-offloading.patch b/target/linux/mediatek/patches-4.14/0035-net-mediatek-disable-RX-VLan-offloading.patch
new file mode 100644
index 0000000000..36321c55cf
--- /dev/null
+++ b/target/linux/mediatek/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
+@@ -643,8 +643,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);
+@@ -1874,7 +1874,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);
+
+ /* disable delay and normal interrupt */
+ mtk_w32(eth, 0, MTK_QDMA_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/mediatek/patches-4.14/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch b/target/linux/mediatek/patches-4.14/0042-net-next-mediatek-honour-special-tag-bit-inside-RX-D.patch
new file mode 100644
index 0000000000..4f2c7b2e6e
--- /dev/null
+++ b/target/linux/mediatek/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
+@@ -933,10 +933,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--;
++ }
+
+ netdev = eth->netdev[mac];
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -284,6 +284,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/mediatek/patches-4.14/0043-net-next-mediatek-enable-special-tag-indication-for-.patch b/target/linux/mediatek/patches-4.14/0043-net-next-mediatek-enable-special-tag-indication-for-.patch
new file mode 100644
index 0000000000..2256325c9c
--- /dev/null
+++ b/target/linux/mediatek/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
+@@ -1894,6 +1894,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
+@@ -76,6 +76,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/mediatek/patches-4.14/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch b/target/linux/mediatek/patches-4.14/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch
new file mode 100644
index 0000000000..51204d4001
--- /dev/null
+++ b/target/linux/mediatek/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
+@@ -742,6 +742,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/mediatek/patches-4.14/0045-net-dsa-mediatek-turn-into-platform-driver.patch b/target/linux/mediatek/patches-4.14/0045-net-dsa-mediatek-turn-into-platform-driver.patch
new file mode 100644
index 0000000000..f9c0a2b5e8
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0045-net-dsa-mediatek-turn-into-platform-driver.patch
@@ -0,0 +1,81 @@
+From 1e33784f665cb95c2af5481d3e776d2d3099921b Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 10 Aug 2017 15:57:17 +0200
+Subject: [PATCH 45/57] net: dsa: mediatek: turn into platform driver
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/dsa/mt7530.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+Index: linux-4.14.12/drivers/net/dsa/mt7530.c
+===================================================================
+--- linux-4.14.12.orig/drivers/net/dsa/mt7530.c
++++ linux-4.14.12/drivers/net/dsa/mt7530.c
+@@ -1049,10 +1049,10 @@ static const struct dsa_switch_ops mt753
+ };
+
+ static int
+-mt7530_probe(struct mdio_device *mdiodev)
++mt7530_probe(struct platform_device *mdiodev)
+ {
+ struct mt7530_priv *priv;
+- struct device_node *dn;
++ struct device_node *dn, *mdio;
+
+ dn = mdiodev->dev.of_node;
+
+@@ -1100,7 +1100,12 @@ mt7530_probe(struct mdio_device *mdiodev
+ }
+ }
+
+- priv->bus = mdiodev->bus;
++ mdio = of_parse_phandle(dn, "dsa,mii-bus", 0);
++ if (!mdio)
++ return -EINVAL;
++ priv->bus = of_mdio_find_bus(mdio);
++ if (!priv->bus)
++ return -EPROBE_DEFER;
+ priv->dev = &mdiodev->dev;
+ priv->ds->priv = priv;
+ priv->ds->ops = &mt7530_switch_ops;
+@@ -1110,8 +1115,8 @@ mt7530_probe(struct mdio_device *mdiodev
+ return dsa_register_switch(priv->ds);
+ }
+
+-static void
+-mt7530_remove(struct mdio_device *mdiodev)
++static int
++mt7530_remove(struct platform_device *mdiodev)
+ {
+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
+ int ret = 0;
+@@ -1128,6 +1133,8 @@ mt7530_remove(struct mdio_device *mdiode
+
+ dsa_unregister_switch(priv->ds);
+ mutex_destroy(&priv->reg_mutex);
++
++ return 0;
+ }
+
+ static const struct of_device_id mt7530_of_match[] = {
+@@ -1135,16 +1142,16 @@ static const struct of_device_id mt7530_
+ { /* sentinel */ },
+ };
+
+-static struct mdio_driver mt7530_mdio_driver = {
++static struct platform_driver mtk_mt7530_driver = {
+ .probe = mt7530_probe,
+ .remove = mt7530_remove,
+- .mdiodrv.driver = {
++ .driver = {
+ .name = "mt7530",
+ .of_match_table = mt7530_of_match,
+ },
+ };
++module_platform_driver(mtk_mt7530_driver);
+
+-mdio_module_driver(mt7530_mdio_driver);
+
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+ MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
diff --git a/target/linux/mediatek/patches-4.14/0046-net-mediatek-add-irq-delay.patch b/target/linux/mediatek/patches-4.14/0046-net-mediatek-add-irq-delay.patch
new file mode 100644
index 0000000000..3c351d345e
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0046-net-mediatek-add-irq-delay.patch
@@ -0,0 +1,23 @@
+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(-)
+
+Index: linux-4.14.11/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+===================================================================
+--- linux-4.14.11.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ linux-4.14.11/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1994,6 +1994,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/mediatek/patches-4.14/0048-net-core-add-RPS-balancer.patch b/target/linux/mediatek/patches-4.14/0048-net-core-add-RPS-balancer.patch
new file mode 100644
index 0000000000..aeb81e14bf
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0048-net-core-add-RPS-balancer.patch
@@ -0,0 +1,90 @@
+From 3e969c9695b45e1a052d43b367096ec99f2f0aac Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 10 Aug 2017 15:58:29 +0200
+Subject: [PATCH 48/57] net: core: add RPS balancer
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ net/core/dev.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 56 insertions(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3551,6 +3551,58 @@ set_rps_cpu(struct net_device *dev, stru
+ return rflow;
+ }
+
++#define RPS_TBL_SIZE_SHIFT 10
++#define RPS_TBL_SIZE (1 << RPS_TBL_SIZE_SHIFT)
++struct rps_table {
++ int core;
++ struct timer_list expire;
++};
++static struct rps_table rps_table[RPS_TBL_SIZE];
++static int rps_table_last_core;
++
++static void rps_table_expire(unsigned long data)
++{
++ struct rps_table *entry = (struct rps_table *) data;
++
++ entry->core = -1;
++}
++
++static int rps_table_core(struct rps_map *map)
++{
++ int i;
++
++ for (i = 0; i < map->len; i++) {
++ int cpu = map->cpus[(rps_table_last_core + i + 1) % map->len];
++ if (cpu_online(cpu)) {
++ rps_table_last_core = cpu;
++ return cpu;
++ }
++ }
++ return map->cpus[0];
++}
++
++static int rps_table_lookup(struct rps_map *map, u32 hash)
++{
++ int bucket = hash & 0x3ff;
++
++ if (rps_table[bucket].core < 0)
++ rps_table[bucket].core = rps_table_core(map);
++ mod_timer(&rps_table[bucket].expire, jiffies + HZ);
++
++ return rps_table[bucket].core;
++}
++
++static void rps_table_init(void)
++{
++ int i;
++
++ for (i = 0; i < RPS_TBL_SIZE; i++) {
++ rps_table[i].core = -1;
++ setup_timer(&rps_table[i].expire, rps_table_expire,
++ (unsigned long) &rps_table[i]);
++ }
++}
++
+ /*
+ * get_rps_cpu is called from netif_receive_skb and returns the target
+ * CPU from the RPS map of the receiving queue for a given skb.
+@@ -3640,7 +3692,7 @@ static int get_rps_cpu(struct net_device
+ try_rps:
+
+ if (map) {
+- tcpu = map->cpus[reciprocal_scale(hash, map->len)];
++ tcpu = rps_table_lookup(map, hash);
+ if (cpu_online(tcpu)) {
+ cpu = tcpu;
+ goto done;
+@@ -8431,6 +8483,9 @@ static int __init net_dev_init(void)
+ sd->backlog.weight = weight_p;
+ }
+
++ if (IS_ENABLED(CONFIG_RPS))
++ rps_table_init();
++
+ dev_boot_phase = 0;
+
+ /* The loopback device is special if any other network devices
diff --git a/target/linux/mediatek/patches-4.14/0051-net-mediatek-increase-tx_timeout.patch b/target/linux/mediatek/patches-4.14/0051-net-mediatek-increase-tx_timeout.patch
new file mode 100644
index 0000000000..3de3e7343b
--- /dev/null
+++ b/target/linux/mediatek/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
+@@ -2384,7 +2384,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/mediatek/patches-4.14/0052-net-phy-add-FC.patch b/target/linux/mediatek/patches-4.14/0052-net-phy-add-FC.patch
new file mode 100644
index 0000000000..32d516ce4d
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0052-net-phy-add-FC.patch
@@ -0,0 +1,21 @@
+From 18b2169d84b47a3414164e5e40f23fb7e875707c Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 10 Aug 2017 16:00:28 +0200
+Subject: [PATCH 52/57] net: phy: add FC
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/phy/phy_device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -1804,7 +1804,7 @@ static struct phy_driver genphy_driver[]
+ .config_init = genphy_config_init,
+ .features = PHY_GBIT_FEATURES | SUPPORTED_MII |
+ SUPPORTED_AUI | SUPPORTED_FIBRE |
+- SUPPORTED_BNC,
++ SUPPORTED_BNC | SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+ .config_aneg = genphy_config_aneg,
+ .aneg_done = genphy_aneg_done,
+ .read_status = genphy_read_status,
diff --git a/target/linux/mediatek/patches-4.14/0062-mdio-atomic.patch b/target/linux/mediatek/patches-4.14/0062-mdio-atomic.patch
new file mode 100644
index 0000000000..96e7072a33
--- /dev/null
+++ b/target/linux/mediatek/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
+@@ -97,7 +97,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/mediatek/patches-4.14/0063-atomic-sleep.patch b/target/linux/mediatek/patches-4.14/0063-atomic-sleep.patch
new file mode 100644
index 0000000000..de49dacd5f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0063-atomic-sleep.patch
@@ -0,0 +1,48 @@
+Index: linux-4.14.12/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+===================================================================
+--- linux-4.14.12.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ linux-4.14.12/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/mediatek/patches-4.14/0064-dts.patch b/target/linux/mediatek/patches-4.14/0064-dts.patch
new file mode 100644
index 0000000000..9120dfc2cd
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0064-dts.patch
@@ -0,0 +1,597 @@
+Index: linux-4.14.18/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+===================================================================
+--- linux-4.14.18.orig/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
++++ linux-4.14.18/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+@@ -21,6 +21,10 @@
+ stdout-path = "serial2:115200n8";
+ };
+
++ memory {
++ reg = <0 0x80000000 0 0x20000000>;
++ };
++
+ cpus {
+ cpu@0 {
+ proc-supply = <&mt6323_vproc_reg>;
+@@ -84,6 +88,10 @@
+ memory@80000000 {
+ reg = <0 0x80000000 0 0x40000000>;
+ };
++
++ mt7530: switch@0 {
++ compatible = "mediatek,mt7530";
++ };
+ };
+
+ &cir {
+@@ -111,11 +119,24 @@
+ };
+ };
+
++ gmac1: mac@1 {
++ compatible = "mediatek,eth-mac";
++ reg = <1>;
++ phy-mode = "rgmii";
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ pause;
++ };
++ };
++
+ mdio: mdio-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+-
+- switch@0 {
++ };
++};
++ &mt7530 {
+ compatible = "mediatek,mt7530";
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -125,6 +146,8 @@
+ core-supply = <&mt6323_vpa_reg>;
+ io-supply = <&mt6323_vemc3v3_reg>;
+
++ dsa,mii-bus = <&mdio>;
++
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -133,29 +156,46 @@
+ port@0 {
+ reg = <0>;
+ label = "wan";
++ cpu = <&cpu_port1>;
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan0";
++ cpu = <&cpu_port0>;
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan1";
++ cpu = <&cpu_port0>;
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan2";
++ cpu = <&cpu_port0>;
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "lan3";
++ cpu = <&cpu_port0>;
+ };
+
+- port@6 {
++ cpu_port1: port@5 {
++ reg = <5>;
++ label = "cpu";
++ ethernet = <&gmac1>;
++ phy-mode = "rgmii";
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
++ };
++
++ cpu_port0: port@6 {
+ reg = <6>;
+ label = "cpu";
+ ethernet = <&gmac0>;
+@@ -168,8 +208,6 @@
+ };
+ };
+ };
+- };
+-};
+
+ &i2c0 {
+ pinctrl-names = "default";
+Index: linux-4.14.18/arch/arm/boot/dts/Makefile
+===================================================================
+--- linux-4.14.18.orig/arch/arm/boot/dts/Makefile
++++ linux-4.14.18/arch/arm/boot/dts/Makefile
+@@ -1061,6 +1061,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
+ mt6580-evbp1.dtb \
+ mt6589-aquaris5.dtb \
+ mt6592-evb.dtb \
++ mt7623a-rfb-emmc.dtb \
+ mt7623n-rfb-nand.dtb \
+ mt7623n-bananapi-bpi-r2.dtb \
+ mt8127-moose.dtb \
+Index: linux-4.14.18/arch/arm/boot/dts/mt7623a-rfb-emmc.dts
+===================================================================
+--- /dev/null
++++ linux-4.14.18/arch/arm/boot/dts/mt7623a-rfb-emmc.dts
+@@ -0,0 +1,449 @@
++/*
++ * Copyright 2017 Sean Wang <sean.wang@mediatek.com>
++ *
++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++ */
++
++/dts-v1/;
++#include <dt-bindings/input/input.h>
++#include "mt7623.dtsi"
++#include "mt6323.dtsi"
++
++/ {
++ model = "MediaTek MT7623N NAND reference board";
++ compatible = "mediatek,mt7623a-rfb-emmc", "mediatek,mt7623";
++
++ aliases {
++ serial2 = &uart2;
++ };
++
++ chosen {
++ bootargs = "earlyprintk block2mtd.block2mtd=/dev/mmcblk0,65536,eMMC,5 mtdparts=eMMC:256k(mbr)ro,512k(uboot)ro,256k(config)ro,256k(factory)ro,32M(kernel),32M(recovery),1024M(rootfs),2048M(usrdata),-(bmtpool) rootfstype=squashfs,jffs2";
++
++ stdout-path = "serial2:115200n8";
++ };
++
++ memory {
++ reg = <0 0x80000000 0 0x20000000>;
++ };
++
++ cpus {
++ cpu@0 {
++ proc-supply = <&mt6323_vproc_reg>;
++ };
++
++ cpu@1 {
++ proc-supply = <&mt6323_vproc_reg>;
++ };
++
++ cpu@2 {
++ proc-supply = <&mt6323_vproc_reg>;
++ };
++
++ cpu@3 {
++ proc-supply = <&mt6323_vproc_reg>;
++ };
++ };
++
++ memory@80000000 {
++ reg = <0 0x80000000 0 0x40000000>;
++ };
++
++ mt7530: switch@0 {
++ compatible = "mediatek,mt7530";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ };
++};
++
++&crypto {
++ status = "okay";
++};
++
++&eth {
++ status = "okay";
++
++ gmac0: mac@0 {
++ compatible = "mediatek,eth-mac";
++ reg = <0>;
++ phy-mode = "trgmii";
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ pause;
++ };
++ };
++
++ gmac1: mac@1 {
++ compatible = "mediatek,eth-mac";
++ reg = <1>;
++ phy-mode = "rgmiii-rxid";
++ phy-handle = <&phy5>;
++ };
++
++ mdio: mdio-bus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ phy5: ethernet-phy@5 {
++ reg = <5>;
++ phy-mode = "rgmii-rxid";
++ };
++ };
++};
++
++&mt7530 {
++ compatible = "mediatek,mt7530";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ pinctrl-names = "default";
++ mediatek,mcm;
++ resets = <&ethsys 2>;
++ reset-names = "mcm";
++ core-supply = <&mt6323_vpa_reg>;
++ io-supply = <&mt6323_vemc3v3_reg>;
++
++ dsa,mii-bus = <&mdio>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++
++ port@0 {
++ reg = <0>;
++ label = "lan0";
++ cpu = <&cpu_port0>;
++ };
++
++ port@1 {
++ reg = <1>;
++ label = "lan1";
++ cpu = <&cpu_port0>;
++ };
++
++ port@2 {
++ reg = <2>;
++ label = "lan2";
++ cpu = <&cpu_port0>;
++ };
++
++ port@3 {
++ reg = <3>;
++ label = "lan3";
++ cpu = <&cpu_port0>;
++ };
++
++ cpu_port0: port@6 {
++ reg = <6>;
++ label = "cpu";
++ ethernet = <&gmac0>;
++ phy-mode = "trgmii";
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
++ };
++ };
++};
++
++&i2c0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0_pins_a>;
++ status = "okay";
++};
++
++&i2c1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins_a>;
++ status = "okay";
++};
++
++&mmc0 {
++ pinctrl-names = "default", "state_uhs";
++ pinctrl-0 = <&mmc0_pins_default>;
++ pinctrl-1 = <&mmc0_pins_uhs>;
++ status = "okay";
++ bus-width = <8>;
++ max-frequency = <50000000>;
++ cap-mmc-highspeed;
++ vmmc-supply = <&mt6323_vemc3v3_reg>;
++ vqmmc-supply = <&mt6323_vio18_reg>;
++ non-removable;
++};
++
++&mmc1 {
++ pinctrl-names = "default", "state_uhs";
++ pinctrl-0 = <&mmc1_pins_default>;
++ pinctrl-1 = <&mmc1_pins_uhs>;
++ status = "okay";
++ bus-width = <4>;
++ max-frequency = <50000000>;
++ cap-sd-highspeed;
++ cd-gpios = <&pio 261 0>;
++ vmmc-supply = <&mt6323_vmch_reg>;
++ vqmmc-supply = <&mt6323_vio18_reg>;
++};
++
++&pio {
++ cir_pins_a:cir@0 {
++ pins_cir {
++ pinmux = <MT7623_PIN_46_IR_FUNC_IR>;
++ bias-disable;
++ };
++ };
++
++ i2c0_pins_a: i2c@0 {
++ pins_i2c0 {
++ pinmux = <MT7623_PIN_75_SDA0_FUNC_SDA0>,
++ <MT7623_PIN_76_SCL0_FUNC_SCL0>;
++ bias-disable;
++ };
++ };
++
++ i2c1_pins_a: i2c@1 {
++ pin_i2c1 {
++ pinmux = <MT7623_PIN_57_SDA1_FUNC_SDA1>,
++ <MT7623_PIN_58_SCL1_FUNC_SCL1>;
++ bias-disable;
++ };
++ };
++
++ i2s0_pins_a: i2s@0 {
++ pin_i2s0 {
++ pinmux = <MT7623_PIN_49_I2S0_DATA_FUNC_I2S0_DATA>,
++ <MT7623_PIN_72_I2S0_DATA_IN_FUNC_I2S0_DATA_IN>,
++ <MT7623_PIN_73_I2S0_LRCK_FUNC_I2S0_LRCK>,
++ <MT7623_PIN_74_I2S0_BCK_FUNC_I2S0_BCK>,
++ <MT7623_PIN_126_I2S0_MCLK_FUNC_I2S0_MCLK>;
++ drive-strength = <MTK_DRIVE_12mA>;
++ bias-pull-down;
++ };
++ };
++
++ i2s1_pins_a: i2s@1 {
++ pin_i2s1 {
++ pinmux = <MT7623_PIN_33_I2S1_DATA_FUNC_I2S1_DATA>,
++ <MT7623_PIN_34_I2S1_DATA_IN_FUNC_I2S1_DATA_IN>,
++ <MT7623_PIN_35_I2S1_BCK_FUNC_I2S1_BCK>,
++ <MT7623_PIN_36_I2S1_LRCK_FUNC_I2S1_LRCK>,
++ <MT7623_PIN_37_I2S1_MCLK_FUNC_I2S1_MCLK>;
++ drive-strength = <MTK_DRIVE_12mA>;
++ bias-pull-down;
++ };
++ };
++
++ mmc0_pins_default: mmc0default {
++ pins_cmd_dat {
++ pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>,
++ <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>,
++ <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>,
++ <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>,
++ <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>,
++ <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>,
++ <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>,
++ <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>,
++ <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>;
++ input-enable;
++ bias-pull-up;
++ };
++
++ pins_clk {
++ pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>;
++ bias-pull-down;
++ };
++
++ pins_rst {
++ pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>;
++ bias-pull-up;
++ };
++ };
++
++ mmc0_pins_uhs: mmc0 {
++ pins_cmd_dat {
++ pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>,
++ <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>,
++ <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>,
++ <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>,
++ <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>,
++ <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>,
++ <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>,
++ <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>,
++ <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>;
++ input-enable;
++ drive-strength = <MTK_DRIVE_2mA>;
++ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++ };
++
++ pins_clk {
++ pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>;
++ drive-strength = <MTK_DRIVE_2mA>;
++ bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
++ };
++
++ pins_rst {
++ pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>;
++ bias-pull-up;
++ };
++ };
++
++ mmc1_pins_default: mmc1default {
++ pins_cmd_dat {
++ pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>,
++ <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>,
++ <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>,
++ <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>,
++ <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>;
++ input-enable;
++ drive-strength = <MTK_DRIVE_4mA>;
++ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
++ };
++
++ pins_clk {
++ pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>;
++ bias-pull-down;
++ drive-strength = <MTK_DRIVE_4mA>;
++ };
++
++ pins_wp {
++ pinmux = <MT7623_PIN_29_EINT7_FUNC_MSDC1_WP>;
++ input-enable;
++ bias-pull-up;
++ };
++
++ pins_insert {
++ pinmux = <MT7623_PIN_261_MSDC1_INS_FUNC_GPIO261>;
++ bias-pull-up;
++ };
++ };
++
++ mmc1_pins_uhs: mmc1 {
++ pins_cmd_dat {
++ pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>,
++ <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>,
++ <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>,
++ <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>,
++ <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>;
++ input-enable;
++ drive-strength = <MTK_DRIVE_4mA>;
++ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
++ };
++
++ pins_clk {
++ pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>;
++ drive-strength = <MTK_DRIVE_4mA>;
++ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
++ };
++ };
++
++ pwm_pins_a: pwm@0 {
++ pins_pwm {
++ pinmux = <MT7623_PIN_203_PWM0_FUNC_PWM0>,
++ <MT7623_PIN_204_PWM1_FUNC_PWM1>,
++ <MT7623_PIN_205_PWM2_FUNC_PWM2>,
++ <MT7623_PIN_206_PWM3_FUNC_PWM3>,
++ <MT7623_PIN_207_PWM4_FUNC_PWM4>;
++ };
++ };
++
++ spi0_pins_a: spi@0 {
++ pins_spi {
++ pinmux = <MT7623_PIN_53_SPI0_CSN_FUNC_SPI0_CS>,
++ <MT7623_PIN_54_SPI0_CK_FUNC_SPI0_CK>,
++ <MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MI>,
++ <MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MO>;
++ bias-disable;
++ };
++ };
++
++ uart0_pins_a: uart@0 {
++ pins_dat {
++ pinmux = <MT7623_PIN_79_URXD0_FUNC_URXD0>,
++ <MT7623_PIN_80_UTXD0_FUNC_UTXD0>;
++ };
++ };
++
++ uart1_pins_a: uart@1 {
++ pins_dat {
++ pinmux = <MT7623_PIN_81_URXD1_FUNC_URXD1>,
++ <MT7623_PIN_82_UTXD1_FUNC_UTXD1>;
++ };
++ };
++};
++
++&pwm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_pins_a>;
++ status = "okay";
++};
++
++&pwrap {
++ mt6323 {
++ mt6323led: led {
++ compatible = "mediatek,mt6323-led";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ led@0 {
++ reg = <0>;
++ label = "bpi-r2:isink:green";
++ default-state = "off";
++ };
++
++ led@1 {
++ reg = <1>;
++ label = "bpi-r2:isink:red";
++ default-state = "off";
++ };
++
++ led@2 {
++ reg = <2>;
++ label = "bpi-r2:isink:blue";
++ default-state = "off";
++ };
++ };
++ };
++};
++
++&spi0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi0_pins_a>;
++ status = "okay";
++};
++
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_pins_a>;
++ status = "disabled";
++};
++
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1_pins_a>;
++ status = "disabled";
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&usb1 {
++ vusb33-supply = <&mt6323_vusb_reg>;
++ status = "okay";
++};
++
++&usb2 {
++ vusb33-supply = <&mt6323_vusb_reg>;
++ status = "okay";
++};
++
++&u3phy1 {
++ status = "okay";
++};
++
++&u3phy2 {
++ status = "okay";
++};
++
+Index: linux-4.14.18/arch/arm/boot/dts/mt7623.dtsi
+===================================================================
+--- linux-4.14.18.orig/arch/arm/boot/dts/mt7623.dtsi
++++ linux-4.14.18/arch/arm/boot/dts/mt7623.dtsi
+@@ -753,6 +753,7 @@
+ "syscon";
+ reg = <0 0x1b000000 0 0x1000>;
+ #clock-cells = <1>;
++ #reset-cells = <1>;
+ };
+
+ eth: ethernet@1b100000 {