[rdk-b][common][bsp][Refactor and sync kernel/wifi from Openwrt]

[Description]
Refactor and sync kernel/wifi from Openwrt

[Release-log]
N/A

diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/702-Revert-net-dsa-b53-Fix-valid-setting-for-MDB-entries.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/702-Revert-net-dsa-b53-Fix-valid-setting-for-MDB-entries.patch
new file mode 100644
index 0000000..d9602fa
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/702-Revert-net-dsa-b53-Fix-valid-setting-for-MDB-entries.patch
@@ -0,0 +1,31 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Wed, 7 Dec 2022 07:57:58 +0100
+Subject: [PATCH] Revert "net: dsa: b53: Fix valid setting for MDB entries"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This reverts commit 1fae6eb0fc91d3ecb539e03f9e4dcd1c53ada553.
+
+Upstream commit was a fix for an overlook of setting "ent.is_valid"
+twice after 5d65b64a3d97 ("net: dsa: b53: Add support for MDB").
+
+Since MDB support was not backported to stable kernels (it's not a bug
+fix) there is nothing to fix there. Backporting this commit resulted in
+"env.is_valid" not being set at all.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+ drivers/net/dsa/b53/b53_common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1551,6 +1551,7 @@ static int b53_arl_op(struct b53_device
+ 
+ 	memset(&ent, 0, sizeof(ent));
+ 	ent.port = port;
++	ent.is_valid = is_valid;
+ 	ent.vid = vid;
+ 	ent.is_static = true;
+ 	memcpy(ent.mac, addr, ETH_ALEN);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/703-v5.5-0001-net-dsa-b53-Add-support-for-MDB.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/703-v5.5-0001-net-dsa-b53-Add-support-for-MDB.patch
new file mode 100644
index 0000000..8349d31
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/703-v5.5-0001-net-dsa-b53-Add-support-for-MDB.patch
@@ -0,0 +1,130 @@
+From 5d65b64a3d97011796b225ce315b3ce0011551e7 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Thu, 24 Oct 2019 12:45:07 -0700
+Subject: [PATCH] net: dsa: b53: Add support for MDB
+
+In preparation for supporting IGMP snooping with or without the use of
+a bridge, add support within b53_common.c to program the ARL entries for
+multicast operations. The key difference is that a multicast ARL entry
+is comprised of a bitmask of enabled ports, instead of a port number.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Vivien Didelot <vivien.didelot@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 62 ++++++++++++++++++++++++++++++--
+ drivers/net/dsa/b53/b53_priv.h   |  8 ++++-
+ 2 files changed, 67 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1549,11 +1549,25 @@ static int b53_arl_op(struct b53_device
+ 		break;
+ 	}
+ 
+-	memset(&ent, 0, sizeof(ent));
+-	ent.port = port;
++	/* For multicast address, the port is a bitmask and the validity
++	 * is determined by having at least one port being still active
++	 */
++	if (!is_multicast_ether_addr(addr)) {
++		ent.port = port;
++		ent.is_valid = is_valid;
++	} else {
++		if (is_valid)
++			ent.port |= BIT(port);
++		else
++			ent.port &= ~BIT(port);
++
++		ent.is_valid = !!(ent.port);
++	}
++
+ 	ent.is_valid = is_valid;
+ 	ent.vid = vid;
+ 	ent.is_static = true;
++	ent.is_age = false;
+ 	memcpy(ent.mac, addr, ETH_ALEN);
+ 	b53_arl_from_entry(&mac_vid, &fwd_entry, &ent);
+ 
+@@ -1672,6 +1686,47 @@ int b53_fdb_dump(struct dsa_switch *ds,
+ }
+ EXPORT_SYMBOL(b53_fdb_dump);
+ 
++int b53_mdb_prepare(struct dsa_switch *ds, int port,
++		    const struct switchdev_obj_port_mdb *mdb)
++{
++	struct b53_device *priv = ds->priv;
++
++	/* 5325 and 5365 require some more massaging, but could
++	 * be supported eventually
++	 */
++	if (is5325(priv) || is5365(priv))
++		return -EOPNOTSUPP;
++
++	return 0;
++}
++EXPORT_SYMBOL(b53_mdb_prepare);
++
++void b53_mdb_add(struct dsa_switch *ds, int port,
++		 const struct switchdev_obj_port_mdb *mdb)
++{
++	struct b53_device *priv = ds->priv;
++	int ret;
++
++	ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, true);
++	if (ret)
++		dev_err(ds->dev, "failed to add MDB entry\n");
++}
++EXPORT_SYMBOL(b53_mdb_add);
++
++int b53_mdb_del(struct dsa_switch *ds, int port,
++		const struct switchdev_obj_port_mdb *mdb)
++{
++	struct b53_device *priv = ds->priv;
++	int ret;
++
++	ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, false);
++	if (ret)
++		dev_err(ds->dev, "failed to delete MDB entry\n");
++
++	return ret;
++}
++EXPORT_SYMBOL(b53_mdb_del);
++
+ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
+ {
+ 	struct b53_device *dev = ds->priv;
+@@ -2050,6 +2105,9 @@ static const struct dsa_switch_ops b53_s
+ 	.port_fdb_del		= b53_fdb_del,
+ 	.port_mirror_add	= b53_mirror_add,
+ 	.port_mirror_del	= b53_mirror_del,
++	.port_mdb_prepare	= b53_mdb_prepare,
++	.port_mdb_add		= b53_mdb_add,
++	.port_mdb_del		= b53_mdb_del,
+ };
+ 
+ struct b53_chip_data {
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -250,7 +250,7 @@ b53_build_op(write48, u64);
+ b53_build_op(write64, u64);
+ 
+ struct b53_arl_entry {
+-	u8 port;
++	u16 port;
+ 	u8 mac[ETH_ALEN];
+ 	u16 vid;
+ 	u8 is_valid:1;
+@@ -351,6 +351,12 @@ int b53_fdb_del(struct dsa_switch *ds, i
+ 		const unsigned char *addr, u16 vid);
+ int b53_fdb_dump(struct dsa_switch *ds, int port,
+ 		 dsa_fdb_dump_cb_t *cb, void *data);
++int b53_mdb_prepare(struct dsa_switch *ds, int port,
++		    const struct switchdev_obj_port_mdb *mdb);
++void b53_mdb_add(struct dsa_switch *ds, int port,
++		 const struct switchdev_obj_port_mdb *mdb);
++int b53_mdb_del(struct dsa_switch *ds, int port,
++		const struct switchdev_obj_port_mdb *mdb);
+ int b53_mirror_add(struct dsa_switch *ds, int port,
+ 		   struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
+ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/703-v5.5-0002-net-dsa-bcm_sf2-Wire-up-MDB-operations.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/703-v5.5-0002-net-dsa-bcm_sf2-Wire-up-MDB-operations.patch
new file mode 100644
index 0000000..98c69fc
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/703-v5.5-0002-net-dsa-bcm_sf2-Wire-up-MDB-operations.patch
@@ -0,0 +1,27 @@
+From 29bb5e8337caf2e3d9802ee6a6804561f125bfcf Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Thu, 24 Oct 2019 12:45:08 -0700
+Subject: [PATCH] net: dsa: bcm_sf2: Wire up MDB operations
+
+Leverage the recently add b53_mdb_{add,del,prepare} functions since they
+work as-is for bcm_sf2.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Vivien Didelot <vivien.didelot@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -981,6 +981,9 @@ static const struct dsa_switch_ops bcm_s
+ 	.set_rxnfc		= bcm_sf2_set_rxnfc,
+ 	.port_mirror_add	= b53_mirror_add,
+ 	.port_mirror_del	= b53_mirror_del,
++	.port_mdb_prepare	= b53_mdb_prepare,
++	.port_mdb_add		= b53_mdb_add,
++	.port_mdb_del		= b53_mdb_del,
+ };
+ 
+ struct bcm_sf2_of_data {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/703-v5.5-0003-net-dsa-bcm_sf2-Add-support-for-optional-reset-contr.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/703-v5.5-0003-net-dsa-bcm_sf2-Add-support-for-optional-reset-contr.patch
new file mode 100644
index 0000000..be62e7f
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/703-v5.5-0003-net-dsa-bcm_sf2-Add-support-for-optional-reset-contr.patch
@@ -0,0 +1,81 @@
+From eee87e4377a4b86dc2eea0ade162b0dc33f40576 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 4 Nov 2019 13:51:39 -0800
+Subject: [PATCH] net: dsa: bcm_sf2: Add support for optional reset controller
+ line
+
+Grab an optional and exclusive reset controller line for the switch and
+manage it during probe/remove functions accordingly. For 7278 devices we
+change bcm_sf2_sw_rst() to use the reset controller line since the
+WATCHDOG_CTRL register does not reset the switch contrary to stated
+documentation.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2.c | 19 +++++++++++++++++++
+ drivers/net/dsa/bcm_sf2.h |  3 +++
+ 2 files changed, 22 insertions(+)
+
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -346,6 +346,18 @@ static int bcm_sf2_sw_rst(struct bcm_sf2
+ {
+ 	unsigned int timeout = 1000;
+ 	u32 reg;
++	int ret;
++
++	/* The watchdog reset does not work on 7278, we need to hit the
++	 * "external" reset line through the reset controller.
++	 */
++	if (priv->type == BCM7278_DEVICE_ID && !IS_ERR(priv->rcdev)) {
++		ret = reset_control_assert(priv->rcdev);
++		if (ret)
++			return ret;
++
++		return reset_control_deassert(priv->rcdev);
++	}
+ 
+ 	reg = core_readl(priv, CORE_WATCHDOG_CTRL);
+ 	reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET;
+@@ -1099,6 +1111,11 @@ static int bcm_sf2_sw_probe(struct platf
+ 	priv->core_reg_align = data->core_reg_align;
+ 	priv->num_cfp_rules = data->num_cfp_rules;
+ 
++	priv->rcdev = devm_reset_control_get_optional_exclusive(&pdev->dev,
++								"switch");
++	if (PTR_ERR(priv->rcdev) == -EPROBE_DEFER)
++		return PTR_ERR(priv->rcdev);
++
+ 	/* Auto-detection using standard registers will not work, so
+ 	 * provide an indication of what kind of device we are for
+ 	 * b53_common to work with
+@@ -1237,6 +1254,8 @@ static int bcm_sf2_sw_remove(struct plat
+ 	dsa_unregister_switch(priv->dev->ds);
+ 	bcm_sf2_cfp_exit(priv->dev->ds);
+ 	bcm_sf2_mdio_unregister(priv);
++	if (priv->type == BCM7278_DEVICE_ID && !IS_ERR(priv->rcdev))
++		reset_control_assert(priv->rcdev);
+ 
+ 	return 0;
+ }
+--- a/drivers/net/dsa/bcm_sf2.h
++++ b/drivers/net/dsa/bcm_sf2.h
+@@ -18,6 +18,7 @@
+ #include <linux/types.h>
+ #include <linux/bitops.h>
+ #include <linux/if_vlan.h>
++#include <linux/reset.h>
+ 
+ #include <net/dsa.h>
+ 
+@@ -64,6 +65,8 @@ struct bcm_sf2_priv {
+ 	void __iomem			*fcb;
+ 	void __iomem			*acb;
+ 
++	struct reset_control		*rcdev;
++
+ 	/* Register offsets indirection tables */
+ 	u32 				type;
+ 	const u16			*reg_offsets;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/704-v5.6-net-dsa-Get-information-about-stacked-DSA-protocol.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/704-v5.6-net-dsa-Get-information-about-stacked-DSA-protocol.patch
new file mode 100644
index 0000000..0a05721
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/704-v5.6-net-dsa-Get-information-about-stacked-DSA-protocol.patch
@@ -0,0 +1,363 @@
+From 4d776482ecc689bdd68627985ac4cb5a6f325953 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Tue, 7 Jan 2020 21:06:05 -0800
+Subject: [PATCH] net: dsa: Get information about stacked DSA protocol
+
+It is possible to stack multiple DSA switches in a way that they are not
+part of the tree (disjoint) but the DSA master of a switch is a DSA
+slave of another. When that happens switch drivers may have to know this
+is the case so as to determine whether their tagging protocol has a
+remove chance of working.
+
+This is useful for specific switch drivers such as b53 where devices
+have been known to be stacked in the wild without the Broadcom tag
+protocol supporting that feature. This allows b53 to continue supporting
+those devices by forcing the disabling of Broadcom tags on the outermost
+switches if necessary.
+
+The get_tag_protocol() function is therefore updated to gain an
+additional enum dsa_tag_protocol argument which denotes the current
+tagging protocol used by the DSA master we are attached to, else
+DSA_TAG_PROTO_NONE for the top of the dsa_switch_tree.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c       | 22 +++++++++++-------
+ drivers/net/dsa/b53/b53_priv.h         |  4 +++-
+ drivers/net/dsa/dsa_loop.c             |  3 ++-
+ drivers/net/dsa/lan9303-core.c         |  3 ++-
+ drivers/net/dsa/lantiq_gswip.c         |  3 ++-
+ drivers/net/dsa/microchip/ksz8795.c    |  3 ++-
+ drivers/net/dsa/microchip/ksz9477.c    |  3 ++-
+ drivers/net/dsa/mt7530.c               |  3 ++-
+ drivers/net/dsa/mv88e6060.c            |  3 ++-
+ drivers/net/dsa/mv88e6xxx/chip.c       |  3 ++-
+ drivers/net/dsa/ocelot/felix.c         |  3 ++-
+ drivers/net/dsa/qca/ar9331.c           |  3 ++-
+ drivers/net/dsa/qca8k.c                |  3 ++-
+ drivers/net/dsa/rtl8366rb.c            |  3 ++-
+ drivers/net/dsa/sja1105/sja1105_main.c |  3 ++-
+ drivers/net/dsa/vitesse-vsc73xx-core.c |  3 ++-
+ include/net/dsa.h                      |  3 ++-
+ net/dsa/dsa2.c                         | 31 ++++++++++++++++++++++++--
+ net/dsa/dsa_priv.h                     |  1 +
+ net/dsa/slave.c                        |  4 +---
+ 20 files changed, 78 insertions(+), 29 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -587,9 +587,8 @@ EXPORT_SYMBOL(b53_disable_port);
+ 
+ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port)
+ {
+-	bool tag_en = !(ds->ops->get_tag_protocol(ds, port) ==
+-			 DSA_TAG_PROTO_NONE);
+ 	struct b53_device *dev = ds->priv;
++	bool tag_en = !(dev->tag_protocol == DSA_TAG_PROTO_NONE);
+ 	u8 hdr_ctl, val;
+ 	u16 reg;
+ 
+@@ -1921,7 +1920,8 @@ static bool b53_can_enable_brcm_tags(str
+ 	return ret;
+ }
+ 
+-enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port)
++enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,
++					   enum dsa_tag_protocol mprot)
+ {
+ 	struct b53_device *dev = ds->priv;
+ 
+@@ -1931,16 +1931,22 @@ enum dsa_tag_protocol b53_get_tag_protoc
+ 	 * misses on multicast addresses (TBD).
+ 	 */
+ 	if (is5325(dev) || is5365(dev) || is539x(dev) || is531x5(dev) ||
+-	    !b53_can_enable_brcm_tags(ds, port))
+-		return DSA_TAG_PROTO_NONE;
++	    !b53_can_enable_brcm_tags(ds, port)) {
++		dev->tag_protocol = DSA_TAG_PROTO_NONE;
++		goto out;
++	}
+ 
+ 	/* Broadcom BCM58xx chips have a flow accelerator on Port 8
+ 	 * which requires us to use the prepended Broadcom tag type
+ 	 */
+-	if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT)
+-		return DSA_TAG_PROTO_BRCM_PREPEND;
++	if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) {
++		dev->tag_protocol = DSA_TAG_PROTO_BRCM_PREPEND;
++		goto out;
++	}
+ 
+-	return DSA_TAG_PROTO_BRCM;
++	dev->tag_protocol = DSA_TAG_PROTO_BRCM;
++out:
++	return dev->tag_protocol;
+ }
+ EXPORT_SYMBOL(b53_get_tag_protocol);
+ 
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -118,6 +118,7 @@ struct b53_device {
+ 	u8 jumbo_size_reg;
+ 	int reset_gpio;
+ 	u8 num_arl_entries;
++	enum dsa_tag_protocol tag_protocol;
+ 
+ 	/* used ports mask */
+ 	u16 enabled_ports;
+@@ -359,7 +360,8 @@ int b53_mdb_del(struct dsa_switch *ds, i
+ 		const struct switchdev_obj_port_mdb *mdb);
+ int b53_mirror_add(struct dsa_switch *ds, int port,
+ 		   struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
+-enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port);
++enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,
++					   enum dsa_tag_protocol mprot);
+ void b53_mirror_del(struct dsa_switch *ds, int port,
+ 		    struct dsa_mall_mirror_tc_entry *mirror);
+ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
+--- a/drivers/net/dsa/dsa_loop.c
++++ b/drivers/net/dsa/dsa_loop.c
+@@ -61,7 +61,8 @@ struct dsa_loop_priv {
+ static struct phy_device *phydevs[PHY_MAX_ADDR];
+ 
+ static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds,
+-						   int port)
++						   int port,
++						   enum dsa_tag_protocol mp)
+ {
+ 	dev_dbg(ds->dev, "%s: port: %d\n", __func__, port);
+ 
+--- a/drivers/net/dsa/lan9303-core.c
++++ b/drivers/net/dsa/lan9303-core.c
+@@ -889,7 +889,8 @@ static int lan9303_check_device(struct l
+ /* ---------------------------- DSA -----------------------------------*/
+ 
+ static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds,
+-						      int port)
++						      int port,
++						      enum dsa_tag_protocol mp)
+ {
+ 	return DSA_TAG_PROTO_LAN9303;
+ }
+--- a/drivers/net/dsa/lantiq_gswip.c
++++ b/drivers/net/dsa/lantiq_gswip.c
+@@ -860,7 +860,8 @@ static int gswip_setup(struct dsa_switch
+ }
+ 
+ static enum dsa_tag_protocol gswip_get_tag_protocol(struct dsa_switch *ds,
+-						    int port)
++						    int port,
++						    enum dsa_tag_protocol mp)
+ {
+ 	return DSA_TAG_PROTO_GSWIP;
+ }
+--- a/drivers/net/dsa/microchip/ksz8795.c
++++ b/drivers/net/dsa/microchip/ksz8795.c
+@@ -645,7 +645,8 @@ static void ksz8795_w_phy(struct ksz_dev
+ }
+ 
+ static enum dsa_tag_protocol ksz8795_get_tag_protocol(struct dsa_switch *ds,
+-						      int port)
++						      int port,
++						      enum dsa_tag_protocol mp)
+ {
+ 	return DSA_TAG_PROTO_KSZ8795;
+ }
+--- a/drivers/net/dsa/microchip/ksz9477.c
++++ b/drivers/net/dsa/microchip/ksz9477.c
+@@ -295,7 +295,8 @@ static void ksz9477_port_init_cnt(struct
+ }
+ 
+ static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
+-						      int port)
++						      int port,
++						      enum dsa_tag_protocol mp)
+ {
+ 	enum dsa_tag_protocol proto = DSA_TAG_PROTO_KSZ9477;
+ 	struct ksz_device *dev = ds->priv;
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -1144,7 +1144,8 @@ mt7530_port_vlan_del(struct dsa_switch *
+ }
+ 
+ static enum dsa_tag_protocol
+-mtk_get_tag_protocol(struct dsa_switch *ds, int port)
++mtk_get_tag_protocol(struct dsa_switch *ds, int port,
++		     enum dsa_tag_protocol mp)
+ {
+ 	struct mt7530_priv *priv = ds->priv;
+ 
+--- a/drivers/net/dsa/mv88e6060.c
++++ b/drivers/net/dsa/mv88e6060.c
+@@ -43,7 +43,8 @@ static const char *mv88e6060_get_name(st
+ }
+ 
+ static enum dsa_tag_protocol mv88e6060_get_tag_protocol(struct dsa_switch *ds,
+-							int port)
++							int port,
++							enum dsa_tag_protocol m)
+ {
+ 	return DSA_TAG_PROTO_TRAILER;
+ }
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -4878,7 +4878,8 @@ static struct mv88e6xxx_chip *mv88e6xxx_
+ }
+ 
+ static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
+-							int port)
++							int port,
++							enum dsa_tag_protocol m)
+ {
+ 	struct mv88e6xxx_chip *chip = ds->priv;
+ 
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1016,7 +1016,8 @@ qca8k_port_fdb_dump(struct dsa_switch *d
+ }
+ 
+ static enum dsa_tag_protocol
+-qca8k_get_tag_protocol(struct dsa_switch *ds, int port)
++qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
++		       enum dsa_tag_protocol mp)
+ {
+ 	return DSA_TAG_PROTO_QCA;
+ }
+--- a/drivers/net/dsa/rtl8366rb.c
++++ b/drivers/net/dsa/rtl8366rb.c
+@@ -964,7 +964,8 @@ static int rtl8366rb_setup(struct dsa_sw
+ }
+ 
+ static enum dsa_tag_protocol rtl8366_get_tag_protocol(struct dsa_switch *ds,
+-						      int port)
++						      int port,
++						      enum dsa_tag_protocol mp)
+ {
+ 	/* For now, the RTL switches are handled without any custom tags.
+ 	 *
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1591,7 +1591,8 @@ static int sja1105_setup_8021q_tagging(s
+ }
+ 
+ static enum dsa_tag_protocol
+-sja1105_get_tag_protocol(struct dsa_switch *ds, int port)
++sja1105_get_tag_protocol(struct dsa_switch *ds, int port,
++			 enum dsa_tag_protocol mp)
+ {
+ 	return DSA_TAG_PROTO_SJA1105;
+ }
+--- a/drivers/net/dsa/vitesse-vsc73xx-core.c
++++ b/drivers/net/dsa/vitesse-vsc73xx-core.c
+@@ -542,7 +542,8 @@ static int vsc73xx_phy_write(struct dsa_
+ }
+ 
+ static enum dsa_tag_protocol vsc73xx_get_tag_protocol(struct dsa_switch *ds,
+-						      int port)
++						      int port,
++						      enum dsa_tag_protocol mp)
+ {
+ 	/* The switch internally uses a 8 byte header with length,
+ 	 * source port, tag, LPA and priority. This is supposedly
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -353,7 +353,8 @@ typedef int dsa_fdb_dump_cb_t(const unsi
+ 			      bool is_static, void *data);
+ struct dsa_switch_ops {
+ 	enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds,
+-						  int port);
++						  int port,
++						  enum dsa_tag_protocol mprot);
+ 
+ 	int	(*setup)(struct dsa_switch *ds);
+ 	void	(*teardown)(struct dsa_switch *ds);
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -631,6 +631,32 @@ static int dsa_port_parse_dsa(struct dsa
+ 	return 0;
+ }
+ 
++static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp,
++						  struct net_device *master)
++{
++	enum dsa_tag_protocol tag_protocol = DSA_TAG_PROTO_NONE;
++	struct dsa_switch *mds, *ds = dp->ds;
++	unsigned int mdp_upstream;
++	struct dsa_port *mdp;
++
++	/* It is possible to stack DSA switches onto one another when that
++	 * happens the switch driver may want to know if its tagging protocol
++	 * is going to work in such a configuration.
++	 */
++	if (dsa_slave_dev_check(master)) {
++		mdp = dsa_slave_to_port(master);
++		mds = mdp->ds;
++		mdp_upstream = dsa_upstream_port(mds, mdp->index);
++		tag_protocol = mds->ops->get_tag_protocol(mds, mdp_upstream,
++							  DSA_TAG_PROTO_NONE);
++	}
++
++	/* If the master device is not itself a DSA slave in a disjoint DSA
++	 * tree, then return immediately.
++	 */
++	return ds->ops->get_tag_protocol(ds, dp->index, tag_protocol);
++}
++
+ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master)
+ {
+ 	struct dsa_switch *ds = dp->ds;
+@@ -638,20 +664,21 @@ static int dsa_port_parse_cpu(struct dsa
+ 	const struct dsa_device_ops *tag_ops;
+ 	enum dsa_tag_protocol tag_protocol;
+ 
+-	tag_protocol = ds->ops->get_tag_protocol(ds, dp->index);
++	tag_protocol = dsa_get_tag_protocol(dp, master);
+ 	tag_ops = dsa_tag_driver_get(tag_protocol);
+ 	if (IS_ERR(tag_ops)) {
+ 		if (PTR_ERR(tag_ops) == -ENOPROTOOPT)
+ 			return -EPROBE_DEFER;
+ 		dev_warn(ds->dev, "No tagger for this switch\n");
++		dp->master = NULL;
+ 		return PTR_ERR(tag_ops);
+ 	}
+ 
++	dp->master = master;
+ 	dp->type = DSA_PORT_TYPE_CPU;
+ 	dp->filter = tag_ops->filter;
+ 	dp->rcv = tag_ops->rcv;
+ 	dp->tag_ops = tag_ops;
+-	dp->master = master;
+ 	dp->dst = dst;
+ 
+ 	return 0;
+--- a/net/dsa/dsa_priv.h
++++ b/net/dsa/dsa_priv.h
+@@ -189,6 +189,7 @@ extern const struct dsa_device_ops notag
+ void dsa_slave_mii_bus_init(struct dsa_switch *ds);
+ int dsa_slave_create(struct dsa_port *dp);
+ void dsa_slave_destroy(struct net_device *slave_dev);
++bool dsa_slave_dev_check(const struct net_device *dev);
+ int dsa_slave_suspend(struct net_device *slave_dev);
+ int dsa_slave_resume(struct net_device *slave_dev);
+ int dsa_slave_register_notifier(void);
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -22,8 +22,6 @@
+ 
+ #include "dsa_priv.h"
+ 
+-static bool dsa_slave_dev_check(const struct net_device *dev);
+-
+ /* slave mii_bus handling ***************************************************/
+ static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg)
+ {
+@@ -1494,7 +1492,7 @@ void dsa_slave_destroy(struct net_device
+ 	free_netdev(slave_dev);
+ }
+ 
+-static bool dsa_slave_dev_check(const struct net_device *dev)
++bool dsa_slave_dev_check(const struct net_device *dev)
+ {
+ 	return dev->netdev_ops == &dsa_slave_netdev_ops;
+ }
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/705-v5.6-0001-net-dsa-b53-Enable-Broadcom-tags-for-531x5-539x-fami.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/705-v5.6-0001-net-dsa-b53-Enable-Broadcom-tags-for-531x5-539x-fami.patch
new file mode 100644
index 0000000..abc2dc8
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/705-v5.6-0001-net-dsa-b53-Enable-Broadcom-tags-for-531x5-539x-fami.patch
@@ -0,0 +1,104 @@
+From 8fab459e69abfd04a66d76423d18ba853fced4ab Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Tue, 7 Jan 2020 21:06:06 -0800
+Subject: [PATCH] net: dsa: b53: Enable Broadcom tags for 531x5/539x families
+
+The BCM531x5 and BCM539x families require that the IMP port be enabled
+within the management page and that management mode (SM_SW_FWD_MODE) be
+turned on. Once this is done, everything works as expected, including
+multicast with standalone DSA devices or bridge devices.
+
+Because such switches are frequencly cascaded with other internal
+Broadcom switches on which we want to enable Broadcom tags, update
+b53_can_enable_brcm_tags() to check the kind of DSA master tagging
+protocol being used, if it is one of the two supported Broadcom tagging
+protocols, force DSA_TAG_PROTO_NONE.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 46 +++++++++++++++++++++++++-------
+ 1 file changed, 37 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -371,8 +371,6 @@ static void b53_enable_vlan(struct b53_d
+ 		b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5);
+ 	}
+ 
+-	mgmt &= ~SM_SW_FWD_MODE;
+-
+ 	if (enable) {
+ 		vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID;
+ 		vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN;
+@@ -608,6 +606,22 @@ void b53_brcm_hdr_setup(struct dsa_switc
+ 		break;
+ 	}
+ 
++	/* Enable management mode if tagging is requested */
++	b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &hdr_ctl);
++	if (tag_en)
++		hdr_ctl |= SM_SW_FWD_MODE;
++	else
++		hdr_ctl &= ~SM_SW_FWD_MODE;
++	b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, hdr_ctl);
++
++	/* Configure the appropriate IMP port */
++	b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &hdr_ctl);
++	if (port == 8)
++		hdr_ctl |= GC_FRM_MGMT_PORT_MII;
++	else if (port == 5)
++		hdr_ctl |= GC_FRM_MGMT_PORT_M;
++	b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, hdr_ctl);
++
+ 	/* Enable Broadcom tags for IMP port */
+ 	b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl);
+ 	if (tag_en)
+@@ -1910,13 +1924,29 @@ static bool b53_possible_cpu_port(struct
+ 	return false;
+ }
+ 
+-static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port)
++static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port,
++				     enum dsa_tag_protocol tag_protocol)
+ {
+ 	bool ret = b53_possible_cpu_port(ds, port);
+ 
+-	if (!ret)
++	if (!ret) {
+ 		dev_warn(ds->dev, "Port %d is not Broadcom tag capable\n",
+ 			 port);
++		return ret;
++	}
++
++	switch (tag_protocol) {
++	case DSA_TAG_PROTO_BRCM:
++	case DSA_TAG_PROTO_BRCM_PREPEND:
++		dev_warn(ds->dev,
++			 "Port %d is stacked to Broadcom tag switch\n", port);
++		ret = false;
++		break;
++	default:
++		ret = true;
++		break;
++	}
++
+ 	return ret;
+ }
+ 
+@@ -1926,12 +1956,10 @@ enum dsa_tag_protocol b53_get_tag_protoc
+ 	struct b53_device *dev = ds->priv;
+ 
+ 	/* Older models (5325, 5365) support a different tag format that we do
+-	 * not support in net/dsa/tag_brcm.c yet. 539x and 531x5 require managed
+-	 * mode to be turned on which means we need to specifically manage ARL
+-	 * misses on multicast addresses (TBD).
++	 * not support in net/dsa/tag_brcm.c yet.
+ 	 */
+-	if (is5325(dev) || is5365(dev) || is539x(dev) || is531x5(dev) ||
+-	    !b53_can_enable_brcm_tags(ds, port)) {
++	if (is5325(dev) || is5365(dev) ||
++	    !b53_can_enable_brcm_tags(ds, port, mprot)) {
+ 		dev->tag_protocol = DSA_TAG_PROTO_NONE;
+ 		goto out;
+ 	}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0001-net-dsa-bcm_sf2-Also-configure-Port-5-for-2Gb-sec-on.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0001-net-dsa-bcm_sf2-Also-configure-Port-5-for-2Gb-sec-on.patch
new file mode 100644
index 0000000..61a037b
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0001-net-dsa-bcm_sf2-Also-configure-Port-5-for-2Gb-sec-on.patch
@@ -0,0 +1,37 @@
+From 7458bd540fa0a90220b9e8c349d910d9dde9caf8 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Fri, 14 Feb 2020 16:32:29 -0800
+Subject: [PATCH] net: dsa: bcm_sf2: Also configure Port 5 for 2Gb/sec on 7278
+
+Either port 5 or port 8 can be used on a 7278 device, make sure that
+port 5 also gets configured properly for 2Gb/sec in that case.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2.c      | 3 +++
+ drivers/net/dsa/bcm_sf2_regs.h | 1 +
+ 2 files changed, 4 insertions(+)
+
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -620,6 +620,9 @@ force_link:
+ 		reg |= RXFLOW_CNTL;
+ 	}
+ 
++	if (priv->type == BCM7278_DEVICE_ID && dsa_is_cpu_port(ds, port))
++		reg |= GMIIP_SPEED_UP_2G;
++
+ 	core_writel(priv, reg, offset);
+ }
+ 
+--- a/drivers/net/dsa/bcm_sf2_regs.h
++++ b/drivers/net/dsa/bcm_sf2_regs.h
+@@ -178,6 +178,7 @@ enum bcm_sf2_reg_offs {
+ #define  RXFLOW_CNTL			(1 << 4)
+ #define  TXFLOW_CNTL			(1 << 5)
+ #define  SW_OVERRIDE			(1 << 6)
++#define  GMIIP_SPEED_UP_2G		(1 << 7)
+ 
+ #define CORE_WATCHDOG_CTRL		0x001e4
+ #define  SOFTWARE_RESET			(1 << 7)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0002-Revert-net-dsa-bcm_sf2-Also-configure-Port-5-for-2Gb.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0002-Revert-net-dsa-bcm_sf2-Also-configure-Port-5-for-2Gb.patch
new file mode 100644
index 0000000..2b99f47
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0002-Revert-net-dsa-bcm_sf2-Also-configure-Port-5-for-2Gb.patch
@@ -0,0 +1,43 @@
+From 3f02735e5da5367e4cd563ce6e5c21ce27922248 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 24 Feb 2020 15:44:26 -0800
+Subject: [PATCH] Revert "net: dsa: bcm_sf2: Also configure Port 5 for 2Gb/sec
+ on 7278"
+
+This reverts commit 7458bd540fa0a90220b9e8c349d910d9dde9caf8 ("net: dsa:
+bcm_sf2: Also configure Port 5 for 2Gb/sec on 7278") as it causes
+advanced congestion buffering issues with 7278 switch devices when using
+their internal Giabit PHY. While this is being debugged, continue with
+conservative defaults that work and do not cause packet loss.
+
+Fixes: 7458bd540fa0 ("net: dsa: bcm_sf2: Also configure Port 5 for 2Gb/sec on 7278")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Vivien Didelot <vivien.didelot@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2.c      | 3 ---
+ drivers/net/dsa/bcm_sf2_regs.h | 1 -
+ 2 files changed, 4 deletions(-)
+
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -620,9 +620,6 @@ force_link:
+ 		reg |= RXFLOW_CNTL;
+ 	}
+ 
+-	if (priv->type == BCM7278_DEVICE_ID && dsa_is_cpu_port(ds, port))
+-		reg |= GMIIP_SPEED_UP_2G;
+-
+ 	core_writel(priv, reg, offset);
+ }
+ 
+--- a/drivers/net/dsa/bcm_sf2_regs.h
++++ b/drivers/net/dsa/bcm_sf2_regs.h
+@@ -178,7 +178,6 @@ enum bcm_sf2_reg_offs {
+ #define  RXFLOW_CNTL			(1 << 4)
+ #define  TXFLOW_CNTL			(1 << 5)
+ #define  SW_OVERRIDE			(1 << 6)
+-#define  GMIIP_SPEED_UP_2G		(1 << 7)
+ 
+ #define CORE_WATCHDOG_CTRL		0x001e4
+ #define  SOFTWARE_RESET			(1 << 7)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0005-net-dsa-b53-Restore-VLAN-entries-upon-re-configurati.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0005-net-dsa-b53-Restore-VLAN-entries-upon-re-configurati.patch
new file mode 100644
index 0000000..cf8be49
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0005-net-dsa-b53-Restore-VLAN-entries-upon-re-configurati.patch
@@ -0,0 +1,48 @@
+From d7a0b1f7652f9f6b7ba0c9d8ad8edd6b8c0c1511 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 30 Mar 2020 14:38:47 -0700
+Subject: [PATCH] net: dsa: b53: Restore VLAN entries upon (re)configuration
+
+The first time b53_configure_vlan() is called we have not configured any
+VLAN entries yet, since that happens later when interfaces get brought
+up. When b53_configure_vlan() is called again from suspend/resume we
+need to restore all VLAN entries though.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -696,7 +696,9 @@ int b53_configure_vlan(struct dsa_switch
+ {
+ 	struct b53_device *dev = ds->priv;
+ 	struct b53_vlan vl = { 0 };
++	struct b53_vlan *v;
+ 	int i, def_vid;
++	u16 vid;
+ 
+ 	def_vid = b53_default_pvid(dev);
+ 
+@@ -717,6 +719,19 @@ int b53_configure_vlan(struct dsa_switch
+ 	if (!is5325(dev) && !is5365(dev))
+ 		b53_set_jumbo(dev, dev->enable_jumbo, false);
+ 
++	/* Upon initial call we have not set-up any VLANs, but upon
++	 * system resume, we need to restore all VLAN entries.
++	 */
++	for (vid = def_vid; vid < dev->num_vlans; vid++) {
++		v = &dev->vlans[vid];
++
++		if (!v->members)
++			continue;
++
++		b53_set_vlan_entry(dev, vid, v);
++		b53_fast_age_vlan(dev, vid);
++	}
++
+ 	return 0;
+ }
+ EXPORT_SYMBOL(b53_configure_vlan);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0006-net-dsa-b53-Prevent-tagged-VLAN-on-port-7-for-7278.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0006-net-dsa-b53-Prevent-tagged-VLAN-on-port-7-for-7278.patch
new file mode 100644
index 0000000..12c9546
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0006-net-dsa-b53-Prevent-tagged-VLAN-on-port-7-for-7278.patch
@@ -0,0 +1,33 @@
+From 88631864da093377ce6d5e60b5639328622a8e5c Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 30 Mar 2020 14:38:48 -0700
+Subject: [PATCH] net: dsa: b53: Prevent tagged VLAN on port 7 for 7278
+
+On 7278, port 7 of the switch connects to the ASP UniMAC which is not
+capable of processing VLAN tagged frames. We can still allow the port to
+be part of a VLAN entry, and we may want it to be untagged on egress on
+that VLAN because of that limitation.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1366,6 +1366,14 @@ int b53_vlan_prepare(struct dsa_switch *
+ 	if ((is5325(dev) || is5365(dev)) && vlan->vid_begin == 0)
+ 		return -EOPNOTSUPP;
+ 
++	/* Port 7 on 7278 connects to the ASP's UniMAC which is not capable of
++	 * receiving VLAN tagged frames at all, we can still allow the port to
++	 * be configured for egress untagged.
++	 */
++	if (dev->chip_id == BCM7278_DEVICE_ID && port == 7 &&
++	    !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED))
++		return -EINVAL;
++
+ 	if (vlan->vid_end >= dev->num_vlans)
+ 		return -ERANGE;
+ 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0007-net-dsa-b53-Deny-enslaving-port-7-for-7278-into-a-br.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0007-net-dsa-b53-Deny-enslaving-port-7-for-7278-into-a-br.patch
new file mode 100644
index 0000000..0cddffa
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0007-net-dsa-b53-Deny-enslaving-port-7-for-7278-into-a-br.patch
@@ -0,0 +1,31 @@
+From 31bfc2d42cae6e8b1440fc5db3f0aba6c5d7e602 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 30 Mar 2020 14:38:49 -0700
+Subject: [PATCH] net: dsa: b53: Deny enslaving port 7 for 7278 into a bridge
+
+On 7278, port 7 connects to the ASP which should only receive frames
+through the use of CFP rules, it is not desirable to have it be part of
+a bridge at all since that would make it pick up unwanted traffic that
+it may not even be able to filter or sustain.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1770,6 +1770,12 @@ int b53_br_join(struct dsa_switch *ds, i
+ 	u16 pvlan, reg;
+ 	unsigned int i;
+ 
++	/* On 7278, port 7 which connects to the ASP should only receive
++	 * traffic from matching CFP rules.
++	 */
++	if (dev->chip_id == BCM7278_DEVICE_ID && port == 7)
++		return -EINVAL;
++
+ 	/* Make this port leave the all VLANs join since we will have proper
+ 	 * VLAN entries from now on
+ 	 */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0008-net-dsa-bcm_sf2-Disable-learning-for-ASP-port.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0008-net-dsa-bcm_sf2-Disable-learning-for-ASP-port.patch
new file mode 100644
index 0000000..c3ba9ae
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0008-net-dsa-bcm_sf2-Disable-learning-for-ASP-port.patch
@@ -0,0 +1,36 @@
+From 8b6b208b69917d88bb3e087f8c9e61c6b05ed571 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 30 Mar 2020 14:38:50 -0700
+Subject: [PATCH] net: dsa: bcm_sf2: Disable learning for ASP port
+
+We don't want to enable learning for the ASP port since it only receives
+directed traffic, this allows us to bypass ARL-driven forwarding rules
+which could conflict with Broadcom tags and/or CFP forwarding.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -173,9 +173,17 @@ static int bcm_sf2_port_setup(struct dsa
+ 	core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
+ 
+ 	/* Enable Broadcom tags for that port if requested */
+-	if (priv->brcm_tag_mask & BIT(port))
++	if (priv->brcm_tag_mask & BIT(port)) {
+ 		b53_brcm_hdr_setup(ds, port);
+ 
++		/* Disable learning on ASP port */
++		if (port == 7) {
++			reg = core_readl(priv, CORE_DIS_LEARN);
++			reg |= BIT(port);
++			core_writel(priv, reg, CORE_DIS_LEARN);
++		}
++	}
++
+ 	/* Configure Traffic Class to QoS mapping, allow each priority to map
+ 	 * to a different queue number
+ 	 */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0009-net-dsa-bcm_sf2-Check-earlier-for-FLOW_EXT-and-FLOW_.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0009-net-dsa-bcm_sf2-Check-earlier-for-FLOW_EXT-and-FLOW_.patch
new file mode 100644
index 0000000..5c445ee
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0009-net-dsa-bcm_sf2-Check-earlier-for-FLOW_EXT-and-FLOW_.patch
@@ -0,0 +1,33 @@
+From 5ae8c0d51ace3bdbfb89c27e7661f081cc9287de Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 30 Mar 2020 14:38:51 -0700
+Subject: [PATCH] net: dsa: bcm_sf2: Check earlier for FLOW_EXT and
+ FLOW_MAC_EXT
+
+We do not currently support matching on FLOW_EXT or FLOW_MAC_EXT, but we
+were not checking for those bits being set in the flow specification.
+
+The check for FLOW_EXT and FLOW_MAC_EXT are separated out because a
+subsequent commit will add support for matching VLAN TCI which are
+covered by FLOW_EXT.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2_cfp.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/bcm_sf2_cfp.c
++++ b/drivers/net/dsa/bcm_sf2_cfp.c
+@@ -878,8 +878,9 @@ static int bcm_sf2_cfp_rule_set(struct d
+ 	int ret = -EINVAL;
+ 
+ 	/* Check for unsupported extensions */
+-	if ((fs->flow_type & FLOW_EXT) && (fs->m_ext.vlan_etype ||
+-	     fs->m_ext.data[1]))
++	if ((fs->flow_type & FLOW_EXT) ||
++	    (fs->flow_type & FLOW_MAC_EXT) ||
++	    fs->m_ext.data[1])
+ 		return -EINVAL;
+ 
+ 	if (fs->location != RX_CLS_LOC_ANY &&
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0010-net-dsa-bcm_sf2-Move-writing-of-CFP_DATA-5-into-slic.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0010-net-dsa-bcm_sf2-Move-writing-of-CFP_DATA-5-into-slic.patch
new file mode 100644
index 0000000..93b47af
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0010-net-dsa-bcm_sf2-Move-writing-of-CFP_DATA-5-into-slic.patch
@@ -0,0 +1,131 @@
+From c2d639d118d27d6419f5848675ed5c112a86910f Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 30 Mar 2020 14:38:52 -0700
+Subject: [PATCH] net: dsa: bcm_sf2: Move writing of CFP_DATA(5) into slicing
+ functions
+
+In preparation for matching VLANs, move the writing of CFP_DATA(5) into
+the IPv4 and IPv6 slicing logic since they are part of the per-flow
+configuration.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2_cfp.c | 64 +++++++++++++++++------------------
+ 1 file changed, 32 insertions(+), 32 deletions(-)
+
+--- a/drivers/net/dsa/bcm_sf2_cfp.c
++++ b/drivers/net/dsa/bcm_sf2_cfp.c
+@@ -261,11 +261,20 @@ static int bcm_sf2_cfp_act_pol_set(struc
+ static void bcm_sf2_cfp_slice_ipv4(struct bcm_sf2_priv *priv,
+ 				   struct flow_dissector_key_ipv4_addrs *addrs,
+ 				   struct flow_dissector_key_ports *ports,
+-				   unsigned int slice_num,
++				   unsigned int slice_num, u8 num_udf,
+ 				   bool mask)
+ {
+ 	u32 reg, offset;
+ 
++	/* UDF_Valid[7:0]	[31:24]
++	 * S-Tag		[23:8]
++	 * C-Tag		[7:0]
++	 */
++	if (mask)
++		core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5));
++	else
++		core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5));
++
+ 	/* C-Tag		[31:24]
+ 	 * UDF_n_A8		[23:8]
+ 	 * UDF_n_A7		[7:0]
+@@ -421,18 +430,11 @@ static int bcm_sf2_cfp_ipv4_rule_set(str
+ 	core_writel(priv, layout->udfs[slice_num].mask_value |
+ 		    udf_upper_bits(num_udf), CORE_CFP_MASK_PORT(6));
+ 
+-	/* UDF_Valid[7:0]	[31:24]
+-	 * S-Tag		[23:8]
+-	 * C-Tag		[7:0]
+-	 */
+-	core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5));
+-
+-	/* Mask all but valid UDFs */
+-	core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5));
+-
+ 	/* Program the match and the mask */
+-	bcm_sf2_cfp_slice_ipv4(priv, ipv4.key, ports.key, slice_num, false);
+-	bcm_sf2_cfp_slice_ipv4(priv, ipv4.mask, ports.mask, SLICE_NUM_MASK, true);
++	bcm_sf2_cfp_slice_ipv4(priv, ipv4.key, ports.key, slice_num,
++			       num_udf, false);
++	bcm_sf2_cfp_slice_ipv4(priv, ipv4.mask, ports.mask, SLICE_NUM_MASK,
++			       num_udf, true);
+ 
+ 	/* Insert into TCAM now */
+ 	bcm_sf2_cfp_rule_addr_set(priv, rule_index);
+@@ -468,11 +470,20 @@ out_err_flow_rule:
+ 
+ static void bcm_sf2_cfp_slice_ipv6(struct bcm_sf2_priv *priv,
+ 				   const __be32 *ip6_addr, const __be16 port,
+-				   unsigned int slice_num,
++				   unsigned int slice_num, u32 udf_bits,
+ 				   bool mask)
+ {
+ 	u32 reg, tmp, val, offset;
+ 
++	/* UDF_Valid[7:0]	[31:24]
++	 * S-Tag		[23:8]
++	 * C-Tag		[7:0]
++	 */
++	if (mask)
++		core_writel(priv, udf_bits << 24, CORE_CFP_MASK_PORT(5));
++	else
++		core_writel(priv, udf_bits << 24, CORE_CFP_DATA_PORT(5));
++
+ 	/* C-Tag		[31:24]
+ 	 * UDF_n_B8		[23:8]	(port)
+ 	 * UDF_n_B7 (upper)	[7:0]	(addr[15:8])
+@@ -704,20 +715,13 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
+ 	reg = layout->udfs[slice_num].mask_value | udf_upper_bits(num_udf);
+ 	core_writel(priv, reg, CORE_CFP_MASK_PORT(6));
+ 
+-	/* UDF_Valid[7:0]	[31:24]
+-	 * S-Tag		[23:8]
+-	 * C-Tag		[7:0]
+-	 */
+-	core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5));
+-
+-	/* Mask all but valid UDFs */
+-	core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5));
+-
+ 	/* Slice the IPv6 source address and port */
+ 	bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->src.in6_u.u6_addr32,
+-			       ports.key->src, slice_num, false);
++			       ports.key->src, slice_num,
++			       udf_lower_bits(num_udf), false);
+ 	bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->src.in6_u.u6_addr32,
+-			       ports.mask->src, SLICE_NUM_MASK, true);
++			       ports.mask->src, SLICE_NUM_MASK,
++			       udf_lower_bits(num_udf), true);
+ 
+ 	/* Insert into TCAM now because we need to insert a second rule */
+ 	bcm_sf2_cfp_rule_addr_set(priv, rule_index[0]);
+@@ -768,16 +772,12 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
+ 		udf_lower_bits(num_udf) << 8;
+ 	core_writel(priv, reg, CORE_CFP_MASK_PORT(6));
+ 
+-	/* Don't care */
+-	core_writel(priv, 0, CORE_CFP_DATA_PORT(5));
+-
+-	/* Mask all */
+-	core_writel(priv, 0, CORE_CFP_MASK_PORT(5));
+-
+ 	bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->dst.in6_u.u6_addr32,
+-			       ports.key->dst, slice_num, false);
++			       ports.key->dst, slice_num,
++			       0, false);
+ 	bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->dst.in6_u.u6_addr32,
+-			       ports.key->dst, SLICE_NUM_MASK, true);
++			       ports.key->dst, SLICE_NUM_MASK,
++			       0, true);
+ 
+ 	/* Insert into TCAM now */
+ 	bcm_sf2_cfp_rule_addr_set(priv, rule_index[1]);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0011-net-dsa-bcm_sf2-Add-support-for-matching-VLAN-TCI.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0011-net-dsa-bcm_sf2-Add-support-for-matching-VLAN-TCI.patch
new file mode 100644
index 0000000..71de609
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0011-net-dsa-bcm_sf2-Add-support-for-matching-VLAN-TCI.patch
@@ -0,0 +1,181 @@
+From 7555020c44db75a0d934dffc0aa6c678b52b2a13 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 30 Mar 2020 14:38:53 -0700
+Subject: [PATCH] net: dsa: bcm_sf2: Add support for matching VLAN TCI
+
+Update relevant code paths to support the programming and matching of
+VLAN TCI, this is the only member of the ethtool_flow_ext that we can
+match, the switch does not permit matching the VLAN Ethernet Type field.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2_cfp.c | 53 +++++++++++++++++++++++++----------
+ 1 file changed, 38 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/dsa/bcm_sf2_cfp.c
++++ b/drivers/net/dsa/bcm_sf2_cfp.c
+@@ -261,6 +261,7 @@ static int bcm_sf2_cfp_act_pol_set(struc
+ static void bcm_sf2_cfp_slice_ipv4(struct bcm_sf2_priv *priv,
+ 				   struct flow_dissector_key_ipv4_addrs *addrs,
+ 				   struct flow_dissector_key_ports *ports,
++				   const __be16 vlan_tci,
+ 				   unsigned int slice_num, u8 num_udf,
+ 				   bool mask)
+ {
+@@ -270,16 +271,17 @@ static void bcm_sf2_cfp_slice_ipv4(struc
+ 	 * S-Tag		[23:8]
+ 	 * C-Tag		[7:0]
+ 	 */
++	reg = udf_lower_bits(num_udf) << 24 | be16_to_cpu(vlan_tci) >> 8;
+ 	if (mask)
+-		core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5));
++		core_writel(priv, reg, CORE_CFP_MASK_PORT(5));
+ 	else
+-		core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5));
++		core_writel(priv, reg, CORE_CFP_DATA_PORT(5));
+ 
+ 	/* C-Tag		[31:24]
+ 	 * UDF_n_A8		[23:8]
+ 	 * UDF_n_A7		[7:0]
+ 	 */
+-	reg = 0;
++	reg = (u32)(be16_to_cpu(vlan_tci) & 0xff) << 24;
+ 	if (mask)
+ 		offset = CORE_CFP_MASK_PORT(4);
+ 	else
+@@ -345,6 +347,7 @@ static int bcm_sf2_cfp_ipv4_rule_set(str
+ 				     struct ethtool_rx_flow_spec *fs)
+ {
+ 	struct ethtool_rx_flow_spec_input input = {};
++	__be16 vlan_tci = 0 , vlan_m_tci = 0xffff;
+ 	const struct cfp_udf_layout *layout;
+ 	unsigned int slice_num, rule_index;
+ 	struct ethtool_rx_flow_rule *flow;
+@@ -369,6 +372,12 @@ static int bcm_sf2_cfp_ipv4_rule_set(str
+ 
+ 	ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1);
+ 
++	/* Extract VLAN TCI */
++	if (fs->flow_type & FLOW_EXT) {
++		vlan_tci = fs->h_ext.vlan_tci;
++		vlan_m_tci = fs->m_ext.vlan_tci;
++	}
++
+ 	/* Locate the first rule available */
+ 	if (fs->location == RX_CLS_LOC_ANY)
+ 		rule_index = find_first_zero_bit(priv->cfp.used,
+@@ -431,10 +440,10 @@ static int bcm_sf2_cfp_ipv4_rule_set(str
+ 		    udf_upper_bits(num_udf), CORE_CFP_MASK_PORT(6));
+ 
+ 	/* Program the match and the mask */
+-	bcm_sf2_cfp_slice_ipv4(priv, ipv4.key, ports.key, slice_num,
+-			       num_udf, false);
+-	bcm_sf2_cfp_slice_ipv4(priv, ipv4.mask, ports.mask, SLICE_NUM_MASK,
+-			       num_udf, true);
++	bcm_sf2_cfp_slice_ipv4(priv, ipv4.key, ports.key, vlan_tci,
++			       slice_num, num_udf, false);
++	bcm_sf2_cfp_slice_ipv4(priv, ipv4.mask, ports.mask, vlan_m_tci,
++			       SLICE_NUM_MASK, num_udf, true);
+ 
+ 	/* Insert into TCAM now */
+ 	bcm_sf2_cfp_rule_addr_set(priv, rule_index);
+@@ -470,6 +479,7 @@ out_err_flow_rule:
+ 
+ static void bcm_sf2_cfp_slice_ipv6(struct bcm_sf2_priv *priv,
+ 				   const __be32 *ip6_addr, const __be16 port,
++				   const __be16 vlan_tci,
+ 				   unsigned int slice_num, u32 udf_bits,
+ 				   bool mask)
+ {
+@@ -479,10 +489,11 @@ static void bcm_sf2_cfp_slice_ipv6(struc
+ 	 * S-Tag		[23:8]
+ 	 * C-Tag		[7:0]
+ 	 */
++	reg = udf_bits << 24 | be16_to_cpu(vlan_tci) >> 8;
+ 	if (mask)
+-		core_writel(priv, udf_bits << 24, CORE_CFP_MASK_PORT(5));
++		core_writel(priv, reg, CORE_CFP_MASK_PORT(5));
+ 	else
+-		core_writel(priv, udf_bits << 24, CORE_CFP_DATA_PORT(5));
++		core_writel(priv, reg, CORE_CFP_DATA_PORT(5));
+ 
+ 	/* C-Tag		[31:24]
+ 	 * UDF_n_B8		[23:8]	(port)
+@@ -490,6 +501,7 @@ static void bcm_sf2_cfp_slice_ipv6(struc
+ 	 */
+ 	reg = be32_to_cpu(ip6_addr[3]);
+ 	val = (u32)be16_to_cpu(port) << 8 | ((reg >> 8) & 0xff);
++	val |= (u32)(be16_to_cpu(vlan_tci) & 0xff) << 24;
+ 	if (mask)
+ 		offset = CORE_CFP_MASK_PORT(4);
+ 	else
+@@ -598,6 +610,11 @@ static int bcm_sf2_cfp_rule_cmp(struct b
+ 
+ 		ret = memcmp(&rule->fs.h_u, &fs->h_u, fs_size);
+ 		ret |= memcmp(&rule->fs.m_u, &fs->m_u, fs_size);
++		/* Compare VLAN TCI values as well */
++		if (rule->fs.flow_type & FLOW_EXT) {
++			ret |= rule->fs.h_ext.vlan_tci != fs->h_ext.vlan_tci;
++			ret |= rule->fs.m_ext.vlan_tci != fs->m_ext.vlan_tci;
++		}
+ 		if (ret == 0)
+ 			break;
+ 	}
+@@ -611,6 +628,7 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
+ 				     struct ethtool_rx_flow_spec *fs)
+ {
+ 	struct ethtool_rx_flow_spec_input input = {};
++	__be16 vlan_tci = 0, vlan_m_tci = 0xffff;
+ 	unsigned int slice_num, rule_index[2];
+ 	const struct cfp_udf_layout *layout;
+ 	struct ethtool_rx_flow_rule *flow;
+@@ -634,6 +652,12 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
+ 
+ 	ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1);
+ 
++	/* Extract VLAN TCI */
++	if (fs->flow_type & FLOW_EXT) {
++		vlan_tci = fs->h_ext.vlan_tci;
++		vlan_m_tci = fs->m_ext.vlan_tci;
++	}
++
+ 	layout = &udf_tcpip6_layout;
+ 	slice_num = bcm_sf2_get_slice_number(layout, 0);
+ 	if (slice_num == UDF_NUM_SLICES)
+@@ -717,10 +741,10 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
+ 
+ 	/* Slice the IPv6 source address and port */
+ 	bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->src.in6_u.u6_addr32,
+-			       ports.key->src, slice_num,
++			       ports.key->src, vlan_tci, slice_num,
+ 			       udf_lower_bits(num_udf), false);
+ 	bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->src.in6_u.u6_addr32,
+-			       ports.mask->src, SLICE_NUM_MASK,
++			       ports.mask->src, vlan_m_tci, SLICE_NUM_MASK,
+ 			       udf_lower_bits(num_udf), true);
+ 
+ 	/* Insert into TCAM now because we need to insert a second rule */
+@@ -773,10 +797,10 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
+ 	core_writel(priv, reg, CORE_CFP_MASK_PORT(6));
+ 
+ 	bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->dst.in6_u.u6_addr32,
+-			       ports.key->dst, slice_num,
++			       ports.key->dst, 0, slice_num,
+ 			       0, false);
+ 	bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->dst.in6_u.u6_addr32,
+-			       ports.key->dst, SLICE_NUM_MASK,
++			       ports.key->dst, 0, SLICE_NUM_MASK,
+ 			       0, true);
+ 
+ 	/* Insert into TCAM now */
+@@ -878,8 +902,7 @@ static int bcm_sf2_cfp_rule_set(struct d
+ 	int ret = -EINVAL;
+ 
+ 	/* Check for unsupported extensions */
+-	if ((fs->flow_type & FLOW_EXT) ||
+-	    (fs->flow_type & FLOW_MAC_EXT) ||
++	if ((fs->flow_type & FLOW_MAC_EXT) ||
+ 	    fs->m_ext.data[1])
+ 		return -EINVAL;
+ 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0012-net-dsa-bcm_sf2-Support-specifying-VLAN-tag-egress-r.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0012-net-dsa-bcm_sf2-Support-specifying-VLAN-tag-egress-r.patch
new file mode 100644
index 0000000..174d76c
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0012-net-dsa-bcm_sf2-Support-specifying-VLAN-tag-egress-r.patch
@@ -0,0 +1,94 @@
+From 8b3abe304c5f1057b7bac70fd5576dfa67e3e2b3 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 30 Mar 2020 14:38:54 -0700
+Subject: [PATCH] net: dsa: bcm_sf2: Support specifying VLAN tag egress rule
+
+The port to which the ASP is connected on 7278 is not capable of
+processing VLAN tags as part of the Ethernet frame, so allow an user to
+configure the egress VLAN policy they want to see applied by purposing
+the h_ext.data[1] field. Bit 0 is used to indicate that 0=tagged,
+1=untagged.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2_cfp.c | 40 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 38 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/bcm_sf2_cfp.c
++++ b/drivers/net/dsa/bcm_sf2_cfp.c
+@@ -13,6 +13,8 @@
+ #include <net/dsa.h>
+ #include <linux/bitmap.h>
+ #include <net/flow_offload.h>
++#include <net/switchdev.h>
++#include <uapi/linux/if_bridge.h>
+ 
+ #include "bcm_sf2.h"
+ #include "bcm_sf2_regs.h"
+@@ -847,7 +849,9 @@ static int bcm_sf2_cfp_rule_insert(struc
+ 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
+ 	s8 cpu_port = ds->ports[port].cpu_dp->index;
+ 	__u64 ring_cookie = fs->ring_cookie;
++	struct switchdev_obj_port_vlan vlan;
+ 	unsigned int queue_num, port_num;
++	u16 vid;
+ 	int ret;
+ 
+ 	/* This rule is a Wake-on-LAN filter and we must specifically
+@@ -867,6 +871,34 @@ static int bcm_sf2_cfp_rule_insert(struc
+ 	      dsa_is_cpu_port(ds, port_num)) ||
+ 	    port_num >= priv->hw_params.num_ports)
+ 		return -EINVAL;
++
++	/* If the rule is matching a particular VLAN, make sure that we honor
++	 * the matching and have it tagged or untagged on the destination port,
++	 * we do this on egress with a VLAN entry. The egress tagging attribute
++	 * is expected to be provided in h_ext.data[1] bit 0. A 1 means untagged,
++	 * a 0 means tagged.
++	 */
++	if (fs->flow_type & FLOW_EXT) {
++		/* We cannot support matching multiple VLAN IDs yet */
++		if ((be16_to_cpu(fs->m_ext.vlan_tci) & VLAN_VID_MASK) !=
++		    VLAN_VID_MASK)
++			return -EINVAL;
++
++		vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
++		vlan.vid_begin = vid;
++		vlan.vid_end = vid;
++		if (cpu_to_be32(fs->h_ext.data[1]) & 1)
++			vlan.flags = BRIDGE_VLAN_INFO_UNTAGGED;
++		else
++			vlan.flags = 0;
++
++		ret = ds->ops->port_vlan_prepare(ds, port_num, &vlan);
++		if (ret)
++			return ret;
++
++		ds->ops->port_vlan_add(ds, port_num, &vlan);
++	}
++
+ 	/*
+ 	 * We have a small oddity where Port 6 just does not have a
+ 	 * valid bit here (so we substract by one).
+@@ -902,14 +934,18 @@ static int bcm_sf2_cfp_rule_set(struct d
+ 	int ret = -EINVAL;
+ 
+ 	/* Check for unsupported extensions */
+-	if ((fs->flow_type & FLOW_MAC_EXT) ||
+-	    fs->m_ext.data[1])
++	if (fs->flow_type & FLOW_MAC_EXT)
+ 		return -EINVAL;
+ 
+ 	if (fs->location != RX_CLS_LOC_ANY &&
+ 	    fs->location > bcm_sf2_cfp_rule_size(priv))
+ 		return -EINVAL;
+ 
++	if ((fs->flow_type & FLOW_EXT) &&
++	    !(ds->ops->port_vlan_prepare || ds->ops->port_vlan_add ||
++	      ds->ops->port_vlan_del))
++		return -EOPNOTSUPP;
++
+ 	if (fs->location != RX_CLS_LOC_ANY &&
+ 	    test_bit(fs->location, priv->cfp.used))
+ 		return -EBUSY;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0016-net-dsa-b53-Fix-valid-setting-for-MDB-entries.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0016-net-dsa-b53-Fix-valid-setting-for-MDB-entries.patch
new file mode 100644
index 0000000..f77aee1
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/707-v5.7-0016-net-dsa-b53-Fix-valid-setting-for-MDB-entries.patch
@@ -0,0 +1,30 @@
+From eab167f4851a19c514469dfa81147f77e17b5b20 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 20 Apr 2020 20:26:52 -0700
+Subject: [PATCH] net: dsa: b53: Fix valid setting for MDB entries
+
+When support for the MDB entries was added, the valid bit was correctly
+changed to be assigned depending on the remaining port bitmask, that is,
+if there were no more ports added to the entry's port bitmask, the entry
+now becomes invalid. There was another assignment a few lines below that
+would override this which would invalidate entries even when there were
+still multiple ports left in the MDB entry.
+
+Fixes: 5d65b64a3d97 ("net: dsa: b53: Add support for MDB")
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1600,7 +1600,6 @@ static int b53_arl_op(struct b53_device
+ 		ent.is_valid = !!(ent.port);
+ 	}
+ 
+-	ent.is_valid = is_valid;
+ 	ent.vid = vid;
+ 	ent.is_static = true;
+ 	ent.is_age = false;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0001-net-dsa-b53-per-port-interrupts-are-optional.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0001-net-dsa-b53-per-port-interrupts-are-optional.patch
new file mode 100644
index 0000000..ee1c883
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0001-net-dsa-b53-per-port-interrupts-are-optional.patch
@@ -0,0 +1,25 @@
+From 007fc3c0ca478f3a8ad687cf9ecbe672d3a64700 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Fri, 17 Apr 2020 11:33:41 -0700
+Subject: [PATCH] net: dsa: b53: per-port interrupts are optional
+
+Make use of platform_get_irq_byname_optional() to avoid printing
+messages on the kernel console that interrupts cannot be found.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_srab.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/b53/b53_srab.c
++++ b/drivers/net/dsa/b53/b53_srab.c
+@@ -524,7 +524,7 @@ static void b53_srab_prepare_irq(struct
+ 
+ 		port->num = i;
+ 		port->dev = dev;
+-		port->irq = platform_get_irq_byname(pdev, name);
++		port->irq = platform_get_irq_byname_optional(pdev, name);
+ 		kfree(name);
+ 	}
+ 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0002-net-dsa-b53-Rename-num_arl_entries-to-num_arl_bins.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0002-net-dsa-b53-Rename-num_arl_entries-to-num_arl_bins.patch
new file mode 100644
index 0000000..7b566dd
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0002-net-dsa-b53-Rename-num_arl_entries-to-num_arl_bins.patch
@@ -0,0 +1,255 @@
+From 673e69a67dd63fc3b40f109d1677a5dc72185fbb Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Thu, 30 Apr 2020 11:49:08 -0700
+Subject: [PATCH] net: dsa: b53: Rename num_arl_entries to num_arl_bins
+
+The variable currently holds the number of ARL bins per ARL buckets,
+which is different from the number of ARL entries which would be bins
+times buckets. We will be adding a num_arl_buckets in a subsequent patch
+so get variables straight now.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 52 ++++++++++++++++----------------
+ drivers/net/dsa/b53/b53_priv.h   |  2 +-
+ 2 files changed, 27 insertions(+), 27 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1506,10 +1506,10 @@ static int b53_arl_read(struct b53_devic
+ 	if (ret)
+ 		return ret;
+ 
+-	bitmap_zero(free_bins, dev->num_arl_entries);
++	bitmap_zero(free_bins, dev->num_arl_bins);
+ 
+ 	/* Read the bins */
+-	for (i = 0; i < dev->num_arl_entries; i++) {
++	for (i = 0; i < dev->num_arl_bins; i++) {
+ 		u64 mac_vid;
+ 		u32 fwd_entry;
+ 
+@@ -1532,10 +1532,10 @@ static int b53_arl_read(struct b53_devic
+ 		return 0;
+ 	}
+ 
+-	if (bitmap_weight(free_bins, dev->num_arl_entries) == 0)
++	if (bitmap_weight(free_bins, dev->num_arl_bins) == 0)
+ 		return -ENOSPC;
+ 
+-	*idx = find_first_bit(free_bins, dev->num_arl_entries);
++	*idx = find_first_bit(free_bins, dev->num_arl_bins);
+ 
+ 	return -ENOENT;
+ }
+@@ -1705,7 +1705,7 @@ int b53_fdb_dump(struct dsa_switch *ds,
+ 		if (ret)
+ 			return ret;
+ 
+-		if (priv->num_arl_entries > 2) {
++		if (priv->num_arl_bins > 2) {
+ 			b53_arl_search_rd(priv, 1, &results[1]);
+ 			ret = b53_fdb_copy(port, &results[1], cb, data);
+ 			if (ret)
+@@ -2179,7 +2179,7 @@ struct b53_chip_data {
+ 	u16 enabled_ports;
+ 	u8 cpu_port;
+ 	u8 vta_regs[3];
+-	u8 arl_entries;
++	u8 arl_bins;
+ 	u8 duplex_reg;
+ 	u8 jumbo_pm_reg;
+ 	u8 jumbo_size_reg;
+@@ -2198,7 +2198,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM5325",
+ 		.vlans = 16,
+ 		.enabled_ports = 0x1f,
+-		.arl_entries = 2,
++		.arl_bins = 2,
+ 		.cpu_port = B53_CPU_PORT_25,
+ 		.duplex_reg = B53_DUPLEX_STAT_FE,
+ 	},
+@@ -2207,7 +2207,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM5365",
+ 		.vlans = 256,
+ 		.enabled_ports = 0x1f,
+-		.arl_entries = 2,
++		.arl_bins = 2,
+ 		.cpu_port = B53_CPU_PORT_25,
+ 		.duplex_reg = B53_DUPLEX_STAT_FE,
+ 	},
+@@ -2216,7 +2216,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM5389",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2228,7 +2228,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM5395",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2240,7 +2240,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM5397",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS_9798,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2252,7 +2252,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM5398",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x7f,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS_9798,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2264,7 +2264,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM53115",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2276,7 +2276,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM53125",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0xff,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2288,7 +2288,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM53128",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1ff,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2300,7 +2300,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM63xx",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0, /* pdata must provide them */
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS_63XX,
+ 		.duplex_reg = B53_DUPLEX_STAT_63XX,
+@@ -2312,7 +2312,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM53010",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2324,7 +2324,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM53011",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1bf,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2336,7 +2336,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM53012",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1bf,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2348,7 +2348,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM53018",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2360,7 +2360,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM53019",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2372,7 +2372,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM585xx/586xx/88312",
+ 		.vlans	= 4096,
+ 		.enabled_ports = 0x1ff,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2384,7 +2384,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM583xx/11360",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x103,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2396,7 +2396,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM7445",
+ 		.vlans	= 4096,
+ 		.enabled_ports = 0x1ff,
+-		.arl_entries = 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2408,7 +2408,7 @@ static const struct b53_chip_data b53_sw
+ 		.dev_name = "BCM7278",
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1ff,
+-		.arl_entries= 4,
++		.arl_bins = 4,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2436,7 +2436,7 @@ static int b53_switch_init(struct b53_de
+ 			dev->jumbo_pm_reg = chip->jumbo_pm_reg;
+ 			dev->cpu_port = chip->cpu_port;
+ 			dev->num_vlans = chip->vlans;
+-			dev->num_arl_entries = chip->arl_entries;
++			dev->num_arl_bins = chip->arl_bins;
+ 			break;
+ 		}
+ 	}
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -117,7 +117,7 @@ struct b53_device {
+ 	u8 jumbo_pm_reg;
+ 	u8 jumbo_size_reg;
+ 	int reset_gpio;
+-	u8 num_arl_entries;
++	u8 num_arl_bins;
+ 	enum dsa_tag_protocol tag_protocol;
+ 
+ 	/* used ports mask */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0003-net-dsa-b53-Provide-number-of-ARL-buckets.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0003-net-dsa-b53-Provide-number-of-ARL-buckets.patch
new file mode 100644
index 0000000..3c278d4
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0003-net-dsa-b53-Provide-number-of-ARL-buckets.patch
@@ -0,0 +1,198 @@
+From e3da4038f4ca1094596a7604c6edac4a6a4f6ee9 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Thu, 30 Apr 2020 11:49:09 -0700
+Subject: [PATCH] net: dsa: b53: Provide number of ARL buckets
+
+In preparation for doing proper upper bound checking of FDB/MDB entries
+being added to the ARL, provide the number of ARL buckets for each
+switch chip we support. All chips have 1024 buckets, except 7278 which
+has only 256.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 21 +++++++++++++++++++++
+ drivers/net/dsa/b53/b53_priv.h   |  1 +
+ 2 files changed, 22 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2180,6 +2180,7 @@ struct b53_chip_data {
+ 	u8 cpu_port;
+ 	u8 vta_regs[3];
+ 	u8 arl_bins;
++	u16 arl_buckets;
+ 	u8 duplex_reg;
+ 	u8 jumbo_pm_reg;
+ 	u8 jumbo_size_reg;
+@@ -2199,6 +2200,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 16,
+ 		.enabled_ports = 0x1f,
+ 		.arl_bins = 2,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT_25,
+ 		.duplex_reg = B53_DUPLEX_STAT_FE,
+ 	},
+@@ -2208,6 +2210,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 256,
+ 		.enabled_ports = 0x1f,
+ 		.arl_bins = 2,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT_25,
+ 		.duplex_reg = B53_DUPLEX_STAT_FE,
+ 	},
+@@ -2217,6 +2220,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2229,6 +2233,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2241,6 +2246,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS_9798,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2253,6 +2259,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x7f,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS_9798,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2265,6 +2272,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2277,6 +2285,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0xff,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2289,6 +2298,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1ff,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2301,6 +2311,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0, /* pdata must provide them */
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS_63XX,
+ 		.duplex_reg = B53_DUPLEX_STAT_63XX,
+@@ -2313,6 +2324,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2325,6 +2337,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1bf,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2337,6 +2350,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1bf,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2349,6 +2363,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2361,6 +2376,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1f,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2373,6 +2389,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans	= 4096,
+ 		.enabled_ports = 0x1ff,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2385,6 +2402,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x103,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2397,6 +2415,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans	= 4096,
+ 		.enabled_ports = 0x1ff,
+ 		.arl_bins = 4,
++		.arl_buckets = 1024,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2409,6 +2428,7 @@ static const struct b53_chip_data b53_sw
+ 		.vlans = 4096,
+ 		.enabled_ports = 0x1ff,
+ 		.arl_bins = 4,
++		.arl_buckets = 256,
+ 		.cpu_port = B53_CPU_PORT,
+ 		.vta_regs = B53_VTA_REGS,
+ 		.duplex_reg = B53_DUPLEX_STAT_GE,
+@@ -2437,6 +2457,7 @@ static int b53_switch_init(struct b53_de
+ 			dev->cpu_port = chip->cpu_port;
+ 			dev->num_vlans = chip->vlans;
+ 			dev->num_arl_bins = chip->arl_bins;
++			dev->num_arl_buckets = chip->arl_buckets;
+ 			break;
+ 		}
+ 	}
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -118,6 +118,7 @@ struct b53_device {
+ 	u8 jumbo_size_reg;
+ 	int reset_gpio;
+ 	u8 num_arl_bins;
++	u16 num_arl_buckets;
+ 	enum dsa_tag_protocol tag_protocol;
+ 
+ 	/* used ports mask */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0004-net-dsa-b53-Bound-check-ARL-searches.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0004-net-dsa-b53-Bound-check-ARL-searches.patch
new file mode 100644
index 0000000..8faf2ac
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0004-net-dsa-b53-Bound-check-ARL-searches.patch
@@ -0,0 +1,43 @@
+From cd169d799beeb738fa2d3e891960924cdcaf8414 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Thu, 30 Apr 2020 11:49:10 -0700
+Subject: [PATCH] net: dsa: b53: Bound check ARL searches
+
+ARL searches are done by reading two ARL entries at a time, do not cap
+the search at 1024 which would only limit us to half of the possible ARL
+capacity, but use b53_max_arl_entries() instead which does the right
+multiplication between bins and indexes.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 2 +-
+ drivers/net/dsa/b53/b53_priv.h   | 5 +++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1715,7 +1715,7 @@ int b53_fdb_dump(struct dsa_switch *ds,
+ 				break;
+ 		}
+ 
+-	} while (count++ < 1024);
++	} while (count++ < b53_max_arl_entries(priv) / 2);
+ 
+ 	return 0;
+ }
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -213,6 +213,11 @@ static inline int is58xx(struct b53_devi
+ #define B53_CPU_PORT_25	5
+ #define B53_CPU_PORT	8
+ 
++static inline unsigned int b53_max_arl_entries(struct b53_device *dev)
++{
++	return dev->num_arl_buckets * dev->num_arl_bins;
++}
++
+ struct b53_device *b53_switch_alloc(struct device *base,
+ 				    const struct b53_io_ops *ops,
+ 				    void *priv);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0005-net-dsa-b53-Remove-is_static-argument-to-b53_read_op.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0005-net-dsa-b53-Remove-is_static-argument-to-b53_read_op.patch
new file mode 100644
index 0000000..e4dad7d
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0005-net-dsa-b53-Remove-is_static-argument-to-b53_read_op.patch
@@ -0,0 +1,36 @@
+From ef2a0bd99b1549a3a4253355be247d5dff25d720 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Thu, 30 Apr 2020 11:49:11 -0700
+Subject: [PATCH] net: dsa: b53: Remove is_static argument to b53_read_op()
+
+This argument is not used.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1495,8 +1495,7 @@ static int b53_arl_rw_op(struct b53_devi
+ }
+ 
+ static int b53_arl_read(struct b53_device *dev, u64 mac,
+-			u16 vid, struct b53_arl_entry *ent, u8 *idx,
+-			bool is_valid)
++			u16 vid, struct b53_arl_entry *ent, u8 *idx)
+ {
+ 	DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
+ 	unsigned int i;
+@@ -1561,7 +1560,8 @@ static int b53_arl_op(struct b53_device
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = b53_arl_read(dev, mac, vid, &ent, &idx, is_valid);
++	ret = b53_arl_read(dev, mac, vid, &ent, &idx);
++
+ 	/* If this is a read, just finish now */
+ 	if (op)
+ 		return ret;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0006-net-dsa-b53-remove-redundant-premature-assignment-to.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0006-net-dsa-b53-remove-redundant-premature-assignment-to.patch
new file mode 100644
index 0000000..1360aa4
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/709-v5.8-0006-net-dsa-b53-remove-redundant-premature-assignment-to.patch
@@ -0,0 +1,28 @@
+From 9f01a71c5cbec10b851588457089d17c20dc5a40 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Wed, 27 May 2020 13:01:29 +0100
+Subject: [PATCH] net: dsa: b53: remove redundant premature assignment to
+ new_pvid
+
+Variable new_pvid is being assigned with a value that is never read,
+the following if statement updates new_pvid with a new value in both
+of the if paths. The assignment is redundant and can be removed.
+
+Addresses-Coverity: ("Unused value")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1336,7 +1336,6 @@ int b53_vlan_filtering(struct dsa_switch
+ 	u16 pvid, new_pvid;
+ 
+ 	b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid);
+-	new_pvid = pvid;
+ 	if (!vlan_filtering) {
+ 		/* Filtering is currently enabled, use the default PVID since
+ 		 * the bridge does not expect tagging anymore
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/745-v5.7-net-dsa-mt7530-add-support-for-port-mirroring.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/745-v5.7-net-dsa-mt7530-add-support-for-port-mirroring.patch
index 71a0699..566dfce 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/745-v5.7-net-dsa-mt7530-add-support-for-port-mirroring.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/745-v5.7-net-dsa-mt7530-add-support-for-port-mirroring.patch
@@ -80,9 +80,9 @@
 +}
 +
  static enum dsa_tag_protocol
- mtk_get_tag_protocol(struct dsa_switch *ds, int port)
- {
-@@ -1520,6 +1578,8 @@ static const struct dsa_switch_ops mt753
+ mtk_get_tag_protocol(struct dsa_switch *ds, int port,
+ 		     enum dsa_tag_protocol mp)
+@@ -1521,6 +1579,8 @@ static const struct dsa_switch_ops mt753
  	.port_vlan_prepare	= mt7530_port_vlan_prepare,
  	.port_vlan_add		= mt7530_port_vlan_add,
  	.port_vlan_del		= mt7530_port_vlan_del,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch
index a45a22e..81acdae 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch
@@ -25,7 +25,7 @@
 
 --- a/drivers/net/dsa/mv88e6xxx/chip.c
 +++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -4928,6 +4928,80 @@ static int mv88e6xxx_port_mdb_del(struct
+@@ -4929,6 +4929,80 @@ static int mv88e6xxx_port_mdb_del(struct
  	return err;
  }
  
@@ -106,7 +106,7 @@
  static int mv88e6xxx_port_egress_floods(struct dsa_switch *ds, int port,
  					 bool unicast, bool multicast)
  {
-@@ -4982,6 +5056,8 @@ static const struct dsa_switch_ops mv88e
+@@ -4983,6 +5057,8 @@ static const struct dsa_switch_ops mv88e
  	.port_mdb_prepare       = mv88e6xxx_port_mdb_prepare,
  	.port_mdb_add           = mv88e6xxx_port_mdb_add,
  	.port_mdb_del           = mv88e6xxx_port_mdb_del,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch
index 837126a..9985e1c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch
@@ -19,7 +19,7 @@
 
 --- a/drivers/net/dsa/mv88e6xxx/chip.c
 +++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -4995,7 +4995,7 @@ static void mv88e6xxx_port_mirror_del(st
+@@ -4996,7 +4996,7 @@ static void mv88e6xxx_port_mirror_del(st
  		if (chip->info->ops->set_egress_port(chip,
  						     direction,
  						     dsa_upstream_port(ds,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/752-v5.8-net-dsa-provide-an-option-for-drivers-to-always-rece.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/752-v5.8-net-dsa-provide-an-option-for-drivers-to-always-rece.patch
index 52d9351..86f1f83 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/752-v5.8-net-dsa-provide-an-option-for-drivers-to-always-rece.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/752-v5.8-net-dsa-provide-an-option-for-drivers-to-always-rece.patch
@@ -83,7 +83,7 @@
  {
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -319,7 +319,7 @@ static int dsa_slave_vlan_add(struct net
+@@ -317,7 +317,7 @@ static int dsa_slave_vlan_add(struct net
  	if (obj->orig_dev != dev)
  		return -EOPNOTSUPP;
  
@@ -92,7 +92,7 @@
  		return 0;
  
  	vlan = *SWITCHDEV_OBJ_PORT_VLAN(obj);
-@@ -386,7 +386,7 @@ static int dsa_slave_vlan_del(struct net
+@@ -384,7 +384,7 @@ static int dsa_slave_vlan_del(struct net
  	if (obj->orig_dev != dev)
  		return -EOPNOTSUPP;
  
@@ -101,7 +101,7 @@
  		return 0;
  
  	/* Do not deprogram the CPU port as it may be shared with other user
-@@ -1120,7 +1120,7 @@ static int dsa_slave_vlan_rx_add_vid(str
+@@ -1118,7 +1118,7 @@ static int dsa_slave_vlan_rx_add_vid(str
  	 * need to emulate the switchdev prepare + commit phase.
  	 */
  	if (dp->bridge_dev) {
@@ -110,7 +110,7 @@
  			return 0;
  
  		/* br_vlan_get_info() returns -EINVAL or -ENOENT if the
-@@ -1154,7 +1154,7 @@ static int dsa_slave_vlan_rx_kill_vid(st
+@@ -1152,7 +1152,7 @@ static int dsa_slave_vlan_rx_kill_vid(st
  	 * need to emulate the switchdev prepare + commit phase.
  	 */
  	if (dp->bridge_dev) {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/753-v5.8-net-dsa-mt7530-fix-VLAN-setup.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/753-v5.8-net-dsa-mt7530-fix-VLAN-setup.patch
index 0804cea..e26829e 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/753-v5.8-net-dsa-mt7530-fix-VLAN-setup.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/753-v5.8-net-dsa-mt7530-fix-VLAN-setup.patch
@@ -41,7 +41,7 @@
  	mutex_lock(&priv->reg_mutex);
  
  	pvid = priv->ports[port].pvid;
-@@ -1232,6 +1220,7 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -1233,6 +1221,7 @@ mt7530_setup(struct dsa_switch *ds)
  	 * as two netdev instances.
  	 */
  	dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/758-v5.8-net-dsa-rtl8366rb-Support-the-CPU-DSA-tag.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/758-v5.8-net-dsa-rtl8366rb-Support-the-CPU-DSA-tag.patch
index b68c033..cabb9d9 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/758-v5.8-net-dsa-rtl8366rb-Support-the-CPU-DSA-tag.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/758-v5.8-net-dsa-rtl8366rb-Support-the-CPU-DSA-tag.patch
@@ -74,9 +74,9 @@
  	if (ret)
  		return ret;
  
-@@ -966,21 +964,8 @@ static int rtl8366rb_setup(struct dsa_sw
- static enum dsa_tag_protocol rtl8366_get_tag_protocol(struct dsa_switch *ds,
- 						      int port)
+@@ -967,21 +965,8 @@ static enum dsa_tag_protocol rtl8366_get
+ 						      int port,
+ 						      enum dsa_tag_protocol mp)
  {
 -	/* For now, the RTL switches are handled without any custom tags.
 -	 *
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/765-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/765-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch
index 7ec2689..3b63037 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/765-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/765-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch
@@ -69,7 +69,7 @@
  
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -70,8 +70,11 @@ static int dsa_slave_open(struct net_dev
+@@ -68,8 +68,11 @@ static int dsa_slave_open(struct net_dev
  	struct dsa_port *dp = dsa_slave_to_port(dev);
  	int err;
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch
index 893eb71..f889489 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch
@@ -25,7 +25,7 @@
 
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1593,7 +1593,9 @@ static void dsa_slave_switchdev_event_wo
+@@ -1591,7 +1591,9 @@ static void dsa_slave_switchdev_event_wo
  
  		err = dsa_port_fdb_add(dp, fdb_info->addr, fdb_info->vid);
  		if (err) {
@@ -36,7 +36,7 @@
  			break;
  		}
  		fdb_info->offloaded = true;
-@@ -1608,9 +1610,11 @@ static void dsa_slave_switchdev_event_wo
+@@ -1606,9 +1608,11 @@ static void dsa_slave_switchdev_event_wo
  
  		err = dsa_port_fdb_del(dp, fdb_info->addr, fdb_info->vid);
  		if (err) {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch
index 275870d..bd1685a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch
@@ -54,7 +54,7 @@
  	struct sk_buff *	(*xmit)(struct sk_buff *skb,
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1568,76 +1568,66 @@ static int dsa_slave_netdevice_event(str
+@@ -1566,76 +1566,66 @@ static int dsa_slave_netdevice_event(str
  	return NOTIFY_DONE;
  }
  
@@ -167,7 +167,7 @@
  }
  
  /* Called under rcu_read_lock() */
-@@ -1645,7 +1635,9 @@ static int dsa_slave_switchdev_event(str
+@@ -1643,7 +1633,9 @@ static int dsa_slave_switchdev_event(str
  				     unsigned long event, void *ptr)
  {
  	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
@@ -177,7 +177,7 @@
  	int err;
  
  	if (event == SWITCHDEV_PORT_ATTR_SET) {
-@@ -1658,20 +1650,32 @@ static int dsa_slave_switchdev_event(str
+@@ -1656,20 +1648,32 @@ static int dsa_slave_switchdev_event(str
  	if (!dsa_slave_dev_check(dev))
  		return NOTIFY_DONE;
  
@@ -213,7 +213,7 @@
  		dev_hold(dev);
  		break;
  	default:
-@@ -1681,10 +1685,6 @@ static int dsa_slave_switchdev_event(str
+@@ -1679,10 +1683,6 @@ static int dsa_slave_switchdev_event(str
  
  	dsa_schedule_work(&switchdev_work->work);
  	return NOTIFY_OK;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch
index b70986f..acc6e16 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch
@@ -20,7 +20,7 @@
 
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1640,31 +1640,29 @@ static int dsa_slave_switchdev_event(str
+@@ -1638,31 +1638,29 @@ static int dsa_slave_switchdev_event(str
  	struct dsa_port *dp;
  	int err;
  
@@ -68,7 +68,7 @@
  		fdb_info = ptr;
  
  		if (!fdb_info->added_by_user) {
-@@ -1677,13 +1675,12 @@ static int dsa_slave_switchdev_event(str
+@@ -1675,13 +1673,12 @@ static int dsa_slave_switchdev_event(str
  		switchdev_work->vid = fdb_info->vid;
  
  		dev_hold(dev);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch
index c7ed406..35266b7 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch
@@ -30,7 +30,7 @@
 
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1653,6 +1653,9 @@ static int dsa_slave_switchdev_event(str
+@@ -1651,6 +1651,9 @@ static int dsa_slave_switchdev_event(str
  
  		dp = dsa_slave_to_port(dev);
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch
index e4ed6e8..e49a97c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch
@@ -172,7 +172,7 @@
  	 */
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1630,6 +1630,25 @@ static void dsa_slave_switchdev_event_wo
+@@ -1628,6 +1628,25 @@ static void dsa_slave_switchdev_event_wo
  		dev_put(dp->slave);
  }
  
@@ -198,7 +198,7 @@
  /* Called under rcu_read_lock() */
  static int dsa_slave_switchdev_event(struct notifier_block *unused,
  				     unsigned long event, void *ptr)
-@@ -1648,10 +1667,37 @@ static int dsa_slave_switchdev_event(str
+@@ -1646,10 +1665,37 @@ static int dsa_slave_switchdev_event(str
  		return notifier_from_errno(err);
  	case SWITCHDEV_FDB_ADD_TO_DEVICE:
  	case SWITCHDEV_FDB_DEL_TO_DEVICE:
@@ -239,7 +239,7 @@
  
  		if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del)
  			return NOTIFY_DONE;
-@@ -1666,18 +1712,13 @@ static int dsa_slave_switchdev_event(str
+@@ -1664,18 +1710,13 @@ static int dsa_slave_switchdev_event(str
  		switchdev_work->port = dp->index;
  		switchdev_work->event = event;
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
index 5fb2fd7..7d37891 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
@@ -199,6 +199,29 @@
     file://610-v5.9-net-bridge-clear-bridge-s-private-skb-space-on-xmit.patch \
     file://700-v5.5-net-core-allow-fast-GRO-for-skbs-with-Ethernet-heade.patch \
     file://701-v5.7-net-dsa-Implement-flow-dissection-for-tag_brcm.c.patch \
+    file://702-Revert-net-dsa-b53-Fix-valid-setting-for-MDB-entries.patch \
+    file://703-v5.5-0001-net-dsa-b53-Add-support-for-MDB.patch \
+    file://703-v5.5-0002-net-dsa-bcm_sf2-Wire-up-MDB-operations.patch \
+    file://703-v5.5-0003-net-dsa-bcm_sf2-Add-support-for-optional-reset-contr.patch \
+    file://704-v5.6-net-dsa-Get-information-about-stacked-DSA-protocol.patch \
+    file://705-v5.6-0001-net-dsa-b53-Enable-Broadcom-tags-for-531x5-539x-fami.patch \
+    file://707-v5.7-0001-net-dsa-bcm_sf2-Also-configure-Port-5-for-2Gb-sec-on.patch \
+    file://707-v5.7-0002-Revert-net-dsa-bcm_sf2-Also-configure-Port-5-for-2Gb.patch \
+    file://707-v5.7-0005-net-dsa-b53-Restore-VLAN-entries-upon-re-configurati.patch \
+    file://707-v5.7-0006-net-dsa-b53-Prevent-tagged-VLAN-on-port-7-for-7278.patch \
+    file://707-v5.7-0007-net-dsa-b53-Deny-enslaving-port-7-for-7278-into-a-br.patch \
+    file://707-v5.7-0008-net-dsa-bcm_sf2-Disable-learning-for-ASP-port.patch \
+    file://707-v5.7-0009-net-dsa-bcm_sf2-Check-earlier-for-FLOW_EXT-and-FLOW_.patch \
+    file://707-v5.7-0010-net-dsa-bcm_sf2-Move-writing-of-CFP_DATA-5-into-slic.patch \
+    file://707-v5.7-0011-net-dsa-bcm_sf2-Add-support-for-matching-VLAN-TCI.patch \
+    file://707-v5.7-0012-net-dsa-bcm_sf2-Support-specifying-VLAN-tag-egress-r.patch \
+    file://707-v5.7-0016-net-dsa-b53-Fix-valid-setting-for-MDB-entries.patch \
+    file://709-v5.8-0001-net-dsa-b53-per-port-interrupts-are-optional.patch \
+    file://709-v5.8-0002-net-dsa-b53-Rename-num_arl_entries-to-num_arl_bins.patch \
+    file://709-v5.8-0003-net-dsa-b53-Provide-number-of-ARL-buckets.patch \
+    file://709-v5.8-0004-net-dsa-b53-Bound-check-ARL-searches.patch \
+    file://709-v5.8-0005-net-dsa-b53-Remove-is_static-argument-to-b53_read_op.patch \
+    file://709-v5.8-0006-net-dsa-b53-remove-redundant-premature-assignment-to.patch \
     file://716-v5.5-net-sfp-move-fwnode-parsing-into-sfp-bus-layer.patch \
     file://717-v5.5-net-sfp-rework-upstream-interface.patch \
     file://718-v5.5-net-sfp-fix-sfp_bus_put-kernel-documentation.patch \
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/761-net-dsa-mt7530-Support-EEE-features.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/761-net-dsa-mt7530-Support-EEE-features.patch
index c2dc35d..93ed193 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/761-net-dsa-mt7530-Support-EEE-features.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/761-net-dsa-mt7530-Support-EEE-features.patch
@@ -9,7 +9,7 @@
 Signed-off-by: René van Dorst <opensource@vdorst.com>
 --- a/drivers/net/dsa/mt7530.c
 +++ b/drivers/net/dsa/mt7530.c
-@@ -1407,9 +1407,13 @@ static void mt7530_phylink_mac_config(st
+@@ -1408,9 +1408,13 @@ static void mt7530_phylink_mac_config(st
  	switch (state->speed) {
  	case SPEED_1000:
  		mcr_new |= PMCR_FORCE_SPEED_1000;
@@ -23,7 +23,7 @@
  		break;
  	}
  	if (state->duplex == DUPLEX_FULL) {
-@@ -1545,6 +1549,54 @@ mt7530_phylink_mac_link_state(struct dsa
+@@ -1546,6 +1550,54 @@ mt7530_phylink_mac_link_state(struct dsa
  	return 1;
  }
  
@@ -78,7 +78,7 @@
  static const struct dsa_switch_ops mt7530_switch_ops = {
  	.get_tag_protocol	= mtk_get_tag_protocol,
  	.setup			= mt7530_setup,
-@@ -1572,6 +1624,8 @@ static const struct dsa_switch_ops mt753
+@@ -1573,6 +1625,8 @@ static const struct dsa_switch_ops mt753
  	.phylink_mac_config	= mt7530_phylink_mac_config,
  	.phylink_mac_link_down	= mt7530_phylink_mac_link_down,
  	.phylink_mac_link_up	= mt7530_phylink_mac_link_up,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch
index d951246..4c0c439 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch
@@ -18,7 +18,7 @@
 
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1698,10 +1698,12 @@ static int dsa_slave_switchdev_event(str
+@@ -1696,10 +1696,12 @@ static int dsa_slave_switchdev_event(str
  		fdb_info = ptr;
  
  		if (dsa_slave_dev_check(dev)) {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch
index 46504ae..14f62ec 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch
@@ -15,7 +15,7 @@
 
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1712,7 +1712,11 @@ static int dsa_slave_switchdev_event(str
+@@ -1710,7 +1710,11 @@ static int dsa_slave_switchdev_event(str
  			struct net_device *br_dev;
  			struct dsa_slave_priv *p;
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch
index e626086..33f4968 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch
@@ -28,7 +28,7 @@
 
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1705,9 +1705,12 @@ static int dsa_slave_switchdev_event(str
+@@ -1703,9 +1703,12 @@ static int dsa_slave_switchdev_event(str
  			else if (!fdb_info->added_by_user)
  				return NOTIFY_OK;
  		} else {
@@ -44,7 +44,7 @@
  			 */
  			struct net_device *br_dev;
  			struct dsa_slave_priv *p;
-@@ -1729,7 +1732,8 @@ static int dsa_slave_switchdev_event(str
+@@ -1727,7 +1730,8 @@ static int dsa_slave_switchdev_event(str
  
  			dp = p->dp->cpu_dp;
  
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
index 65b0e10..dc9e61e 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
@@ -17,7 +17,7 @@
 
 --- a/drivers/net/dsa/mv88e6xxx/chip.c
 +++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -5082,6 +5082,7 @@ static int mv88e6xxx_register_switch(str
+@@ -5083,6 +5083,7 @@ static int mv88e6xxx_register_switch(str
  	ds->ops = &mv88e6xxx_switch_ops;
  	ds->ageing_time_min = chip->info->age_time_coeff;
  	ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988-clkitg.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988-clkitg.dtsi
index 14739ac..971a171 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988-clkitg.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988-clkitg.dtsi
@@ -103,7 +103,7 @@
 			<&topckgen CK_TOP_NETSYS_PAO_2X_SEL>,
 			<&topckgen CK_TOP_EIP197_SEL>,
 			<&topckgen CK_TOP_AXI_INFRA_SEL>,
-			<&topckgen CK_TOP_UART_SEL>,
+			<&system_clk>,
 			<&topckgen CK_TOP_EMMC_250M_SEL>,
 			<&topckgen CK_TOP_EMMC_400M_SEL>,
 			<&topckgen CK_TOP_SPI_SEL>,
@@ -176,11 +176,11 @@
 			<&infracfg CK_INFRA_FAUD_AUD_O>,
 			<&infracfg CK_INFRA_FAUD_EG2_O>,
 			<&infracfg CK_INFRA_I2C_O>,
-			<&infracfg CK_INFRA_UART_O0>,
-			<&infracfg CK_INFRA_UART_O1>,
-			<&infracfg CK_INFRA_UART_O2>,
+			<&system_clk>,
 			<&system_clk>,
 			<&system_clk>,
+			<&system_clk>,
+			<&system_clk>,
 			<&infracfg CK_INFRA_SPI0_O>,
 			<&infracfg CK_INFRA_SPI1_O>,
 			<&infracfg CK_INFRA_LB_MUX_FRTC>,
@@ -233,11 +233,11 @@
 			<&infracfg_ao CK_INFRA_PRE_CK_SEJ_F13M>,
 			<&system_clk>,
 			<&infracfg_ao CK_INFRA_I2C_BCK>,
-			<&infracfg_ao CK_INFRA_52M_UART0_CK>,
-			<&infracfg_ao CK_INFRA_52M_UART1_CK>,
-			<&infracfg_ao CK_INFRA_52M_UART2_CK>,
+			<&system_clk>,
 			<&system_clk>,
 			<&system_clk>,
+			<&system_clk>,
+			<&system_clk>,
 			<&infracfg_ao CK_INFRA_66M_NFI_HCK>,
 			<&infracfg_ao CK_INFRA_104M_SPI0>,
 			<&infracfg_ao CK_INFRA_104M_SPI1>,
@@ -289,9 +289,9 @@
 			<&system_clk>,
 			<&system_clk>,
 			<&system_clk>,
+			<&system_clk>,
-			<&infracfg_ao CK_INFRA_MUX_UART0_SEL>,
-			<&infracfg_ao CK_INFRA_MUX_UART1_SEL>,
-			<&infracfg_ao CK_INFRA_MUX_UART2_SEL>,
+			<&system_clk>,
+			<&system_clk>,
 			<&infracfg_ao CK_INFRA_MUX_SPI0_SEL>,
 			<&infracfg_ao CK_INFRA_MUX_SPI1_SEL>,
 			<&infracfg_ao CK_INFRA_MUX_SPI2_SEL>,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
index e7f5b6d..8e08930 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
@@ -338,12 +338,6 @@
 		#clock-cells = <0>;
 	};
 
-	uart_clk: dummy_uart_clk {
-		compatible = "fixed-clock";
-		clock-frequency = <40000000>;
-		#clock-cells = <0>;
-	};
-
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupt-parent = <&gic>;
@@ -395,7 +389,12 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11000000 0 0x100>;
 		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&uart_clk>;
+		clocks = <&infracfg_ao CK_INFRA_52M_UART0_CK>;
+		clock-names = "bus";
+		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+				  <&infracfg_ao CK_INFRA_MUX_UART0_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+					 <&infracfg CK_INFRA_UART_O0>;
 		status = "disabled";
 	};
 
@@ -404,7 +403,12 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11000100 0 0x100>;
 		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&uart_clk>;
+		clocks = <&infracfg_ao CK_INFRA_52M_UART1_CK>;
+		clock-names = "bus";
+		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+				  <&infracfg_ao CK_INFRA_MUX_UART1_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+					 <&infracfg CK_INFRA_UART_O1>;
 		status = "disabled";
 	};
 
@@ -413,7 +417,12 @@
 			     "mediatek,mt6577-uart";
 		reg = <0 0x11000200 0 0x100>;
 		interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&uart_clk>;
+		clocks = <&infracfg_ao CK_INFRA_52M_UART2_CK>;
+		clock-names = "bus";
+		assigned-clocks = <&topckgen CK_TOP_UART_SEL>,
+				  <&infracfg_ao CK_INFRA_MUX_UART2_SEL>;
+		assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>,
+					 <&infracfg CK_INFRA_UART_O2>;
 		status = "disabled";
 	};
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-sfp-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-sfp-spim-nand.dts
index 70410b6..5718dfc 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-sfp-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-sfp-spim-nand.dts
@@ -80,13 +80,15 @@
 
 	sfp_esp0: sfp@0 {
 		compatible = "sff,sfp";
-		i2c-bus = <&i2c2>;
+		i2c-bus = <&i2c1>;
+		mod-def0-gpios = <&pio 35 1>;
 		tx-disable-gpios = <&pio 29 0>;
 	};
 
 	sfp_esp1: sfp@1 {
 		compatible = "sff,sfp";
-		i2c-bus = <&i2c1>;
+		i2c-bus = <&i2c2>;
+		mod-def0-gpios = <&pio 82 1>;
 		tx-disable-gpios = <&pio 36 0>;
 	};
 };
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-ids.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-ids.c
index f1812bb..339a304 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-ids.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand-ids.c
@@ -90,6 +90,10 @@
 		   &snand_cap_read_from_cache_quad,
 		   &snand_cap_program_load_x4,
 		   mtk_snand_winbond_select_die),
+	SNAND_INFO("W25N01KV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xae, 0x21),
+		   SNAND_MEMORG_1G_2K_64,
+		   &snand_cap_read_from_cache_quad,
+		   &snand_cap_program_load_x4),
 	SNAND_INFO("W25N02KV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x22),
 		   SNAND_MEMORG_2G_2K_128,
 		   &snand_cap_read_from_cache_quad,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 98507af..89f1150 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4041,9 +4041,10 @@
 
 			if (!of_property_read_string(to_of_node(fixed_node),
 						     "label", &label)) {
-				if (strlen(label) < 16)
-					strcpy(phylink_priv->label, label);
-				else
+				if (strlen(label) < 16) {
+					strncpy(phylink_priv->label, label,
+						strlen(label));
+				} else
 					dev_err(eth->dev, "insufficient space for label!\n");
 			}
 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 45b2e24..2f54f96 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -861,6 +861,16 @@
 #define CO_QPHY_SEL            BIT(0)
 #define GEPHY_MAC_SEL          BIT(1)
 
+/* Toprgu subsystem config registers */
+#define TOPRGU_SWSYSRST		0x18
+#define SWSYSRST_UNLOCK_KEY	GENMASK(31, 24)
+#define SWSYSRST_XFI_PLL_GRST	BIT(16)
+#define SWSYSRST_XFI_PEXPT1_GRST	BIT(15)
+#define SWSYSRST_XFI_PEXPT0_GRST	BIT(14)
+#define SWSYSRST_SGMII1_GRST	BIT(2)
+#define SWSYSRST_SGMII0_GRST	BIT(1)
+#define TOPRGU_SWSYSRST_EN		0xFC
+
 /* Top misc registers */
 #define TOP_MISC_NETSYS_PCS_MUX	0x84
 #define NETSYS_PCS_MUX_MASK	GENMASK(1, 0)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
index 81d528f..9c0d691 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
@@ -1298,7 +1298,7 @@
 	if (copy_from_user(line, buf, length))
 		return -EFAULT;
 
-	if (sscanf(line, "%s %d", name, &enable) != 2)
+	if (sscanf(line, "%15s %1d", name, &enable) != 2)
 		return -EFAULT;
 
 	line[length] = '\0';
@@ -1313,6 +1313,7 @@
 			mtk_ppe_dev_unregister_hook(dev);
 			pr_info("unregister wifi extern if = %s\n", dev->name);
 		}
+		dev_put(dev);
 	} else {
 		pr_info("no such device!\n");
 	}
@@ -2015,9 +2016,18 @@
 	if (copy_from_user(line, buf, length))
 		return -EFAULT;
 
-	if (sscanf(line, "%d %s %d", &enable, scheduling, &rate) != 3)
+	if (sscanf(line, "%1d %3s %9d", &enable, scheduling, &rate) != 3)
 		return -EFAULT;
 
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
+	if (rate > 100000000 || rate < 0 ||
+	    rate > 100000000 || rate < 0)
+#else
+	if (rate > 10000000 || rate < 0 ||
+	    rate > 10000000 || rate < 0)
+#endif
+		return -EINVAL;
+
 	while (rate > 127) {
 		rate /= 10;
 		exp++;
@@ -2688,7 +2698,8 @@
 
 	buf[len] = '\0';
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
-	if (sscanf(buf, "%d %x %x %x %hx %hx %x %x %x %hx %hx %s %s %x %x %x",
+	if (sscanf(buf,
+		   "%5d %8x %8x %8x %hx %hx %8x %8x %8x %hx %hx %18s %18s %4x %4x %4x",
 		   &hash,
 		   &entry.ipv4_hnapt.info_blk1,
 		   &entry.ipv4_hnapt.sip,
@@ -2703,27 +2714,20 @@
 		   dmac_str, smac_str, &tport_id, &tops_entry, &cdrt_id) != 16)
 		return -EFAULT;
 
-	entry.ipv4_hnapt.tport_id = tport_id;
-	entry.ipv4_hnapt.tops_entry = tops_entry;
-	entry.ipv4_hnapt.cdrt_id = cdrt_id;
-
-	if ((hash >= hnat_priv->foe_etry_num) || (hash < -1) ||
-	    (tport_id > 16) || (tport_id < 0) ||
-	    (tops_entry > 64) || (tops_entry < 0) ||
-	    (cdrt_id > 255) || (cdrt_id < 0) ||
-	    (entry.ipv4_hnapt.sport > 65535) ||
-	    (entry.ipv4_hnapt.sport < 0) ||
-	    (entry.ipv4_hnapt.dport > 65535) ||
-	    (entry.ipv4_hnapt.dport < 0) ||
-	    (entry.ipv4_hnapt.new_sport > 65535) ||
-	    (entry.ipv4_hnapt.new_sport < 0) ||
-	    (entry.ipv4_hnapt.new_dport > 65535) ||
-	    (entry.ipv4_hnapt.new_dport < 0)) {
+	if ((hash >= (int)hnat_priv->foe_etry_num) || (hash < -1) ||
+	    (TPORT_ID(tport_id) != tport_id) ||
+	    (TOPS_ENTRY(tops_entry) != tops_entry) ||
+	    (CDRT_ID(cdrt_id) != cdrt_id)) {
 		hnat_static_entry_help();
 		return -EFAULT;
 	}
+
+	entry.ipv4_hnapt.tport_id = tport_id;
+	entry.ipv4_hnapt.tops_entry = tops_entry;
+	entry.ipv4_hnapt.cdrt_id = cdrt_id;
 #else
-	if (sscanf(buf, "%d %x %x %x %hx %hx %x %x %x %hx %hx %s %s",
+	if (sscanf(buf,
+		   "%5d %8x %8x %8x %hx %hx %8x %8x %8x %hx %hx %18s %18s",
 		   &hash,
 		   &entry.ipv4_hnapt.info_blk1,
 		   &entry.ipv4_hnapt.sip,
@@ -2738,15 +2742,7 @@
 		   dmac_str, smac_str) != 13)
 		return -EFAULT;
 
-	if ((hash >= hnat_priv->foe_etry_num) || (hash < -1) ||
-	    (entry.ipv4_hnapt.sport > 65535) ||
-	    (entry.ipv4_hnapt.sport < 0) ||
-	    (entry.ipv4_hnapt.dport > 65535) ||
-	    (entry.ipv4_hnapt.dport < 0) ||
-	    (entry.ipv4_hnapt.new_sport > 65535) ||
-	    (entry.ipv4_hnapt.new_sport < 0) ||
-	    (entry.ipv4_hnapt.new_dport > 65535) ||
-	    (entry.ipv4_hnapt.new_dport < 0)) {
+	if ((hash >= (int)hnat_priv->foe_etry_num) || (hash < -1)) {
 		hnat_static_entry_help();
 		return -EFAULT;
 	}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index 02ec4f0..d2e09e2 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -1230,15 +1230,16 @@
 
 				entry.ipv4_hnapt.vlan1 = hw_path->vlan_id;
 
-				if (skb->vlan_tci && FROM_GE_WAN(skb) &&
-				    IS_LAN_GRP(dev)) {
+				if (skb_vlan_tag_present(skb)) {
 					entry.bfib1.vlan_layer += 1;
 
 					if (entry.ipv4_hnapt.vlan1)
-						entry.ipv4_hnapt.vlan2 = (skb->vlan_tci & VLAN_VID_MASK);
+						entry.ipv4_hnapt.vlan2 =
+							skb->vlan_tci;
 					else
-						entry.ipv4_hnapt.vlan1 = (skb->vlan_tci & VLAN_VID_MASK);
-				}
+						entry.ipv4_hnapt.vlan1 =
+							skb->vlan_tci;
+			}
 
 				entry.ipv4_hnapt.sip = foe->ipv4_hnapt.sip;
 				entry.ipv4_hnapt.dip = foe->ipv4_hnapt.dip;
@@ -1283,14 +1284,15 @@
 
 			entry.ipv6_5t_route.vlan1 = hw_path->vlan_id;
 
-			if (skb->vlan_tci && FROM_GE_WAN(skb) &&
-			    IS_LAN_GRP(dev)) {
+			if (skb_vlan_tag_present(skb)) {
 				entry.bfib1.vlan_layer += 1;
 
 				if (entry.ipv6_5t_route.vlan1)
-					entry.ipv6_5t_route.vlan2 = (skb->vlan_tci & VLAN_VID_MASK);
+					entry.ipv6_5t_route.vlan2 =
+						skb->vlan_tci;
 				else
-					entry.ipv6_5t_route.vlan1 = (skb->vlan_tci & VLAN_VID_MASK);
+					entry.ipv6_5t_route.vlan1 =
+						skb->vlan_tci;
 			}
 
 			if (hnat_priv->data->per_flow_accounting)
@@ -1737,6 +1739,9 @@
 	    (gmac_no != NR_WHNAT_WDMA_PORT))
 		return NF_ACCEPT;
 
+	if (unlikely(!skb_mac_header_was_set(skb)))
+		return NF_ACCEPT;
+
 	if (!skb_hnat_is_hashed(skb))
 		return NF_ACCEPT;
 
@@ -1968,6 +1973,9 @@
 				__func__, dev->name, i);
 			return;
 		}
+	}
+
+	for (i = 1; i < MAX_IF_NUM; i++) {
 		if (!hnat_priv->wifi_hook_if[i]) {
 			if (find_extif_from_devname(dev->name)) {
 				extif_set_dev(dev);
@@ -2113,6 +2121,9 @@
 					  !IS_SPACE_AVAILABLE_HEAD(skb)))
 		return 0;
 
+	if (unlikely(!skb_mac_header_was_set(skb)))
+		return 0;
+
 	if (unlikely(!skb_hnat_is_hashed(skb)))
 		return 0;
 
@@ -2305,7 +2316,12 @@
 mtk_pong_hqos_handler(void *priv, struct sk_buff *skb,
 		      const struct nf_hook_state *state)
 {
-	struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb_mac_header(skb);
+	struct vlan_ethhdr *veth;
+
+	if (!skb)
+		goto drop;
+
+	veth = (struct vlan_ethhdr *)skb_mac_header(skb);
 
 	if (IS_HQOS_MODE && eth_hdr(skb)->h_proto == HQOS_MAGIC_TAG) {
 		skb_hnat_entry(skb) = ntohs(veth->h_vlan_TCI) & 0x3fff;
@@ -2516,7 +2532,8 @@
 	skb_hnat_entry(skb) = ntohs(veth->h_vlan_TCI) & 0x3fff;
 	skb_hnat_reason(skb) = HIT_BIND_FORCE_TO_CPU;
 
-	do_hnat_ge_to_ext(skb, __func__);
+	if (do_hnat_ge_to_ext(skb, __func__) == -1)
+		return 1;
 
 	return 0;
 }
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
index 23a95fd..2a3c7f8 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
@@ -159,6 +159,10 @@
 #define HIT_BIND_PACKET_SAMPLING 0x1B
 #define HIT_BIND_EXCEED_MTU 0x1C
 
+#define TPORT_ID(x) ((x) & GENMASK(3, 0))
+#define TOPS_ENTRY(x) ((x) & GENMASK(5, 0))
+#define CDRT_ID(x) ((x) & GENMASK(7, 0))
+
 u32 hnat_tx(struct sk_buff *skb);
 u32 hnat_set_skb_info(struct sk_buff *skb, u32 *rxd);
 u32 hnat_reg(struct net_device *, void __iomem *);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.c
index 5219bc5..4d85f50 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.c
@@ -121,6 +121,7 @@
 	struct ahash_export_state istate, ostate;
 	unsigned char *key_aalg;
 	unsigned char *key_ealg;
+	unsigned int checksum;
 	unsigned int key_len;
 	int i;
 	int cdrt_idx;
@@ -162,7 +163,6 @@
 		context->control1 = CTRL_WORD1_OUT;
 		memcpy(context->data + 38, &xs->props.saddr.a4, 4);
 		memcpy(context->data + 42, &xs->id.daddr.a4, 4);
-		context->data[39] = 0x00005938;
 		context->data[46] = 0x04020000;
 		context->data[49] = 0x9e14ed69;
 		context->data[50] = 0x01020c10;
@@ -175,6 +175,16 @@
 	context->data[48] = 0x00f00008;
 	context->data[51] = 0x94119411;
 
+	/* Calculate Checksum */
+	checksum = 0;
+	checksum += context->data[38] % 0x10000;
+	checksum += context->data[38] / 0x10000;
+	checksum += context->data[42] % 0x10000;
+	checksum += context->data[42] / 0x10000;
+	checksum += checksum / 0x10000;
+	checksum = checksum % 0x10000;
+	context->data[39] = checksum;
+
 	/* EIP-96 context words[2...39]*/
 	if (strcmp(xs->aalg->alg_name, "hmac(sha1)") == 0) {
 		key_aalg = &xs->aalg->alg_key[0];
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
index 64a6353..ac77ef2 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -37,6 +37,79 @@
 	return 0;
 }
 
+void mtk_sgmii_reset(struct mtk_xgmii *ss, int mac_id)
+{
+	struct mtk_eth *eth = ss->eth;
+	u32 id = mtk_mac2xgmii_id(eth, mac_id);
+	u32 val = 0;
+
+	if (id >= MTK_MAX_DEVS || !eth->toprgu)
+		return;
+
+	switch (mac_id) {
+	case MTK_GMAC2_ID:
+		/* Enable software reset */
+		regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+		val |= SWSYSRST_XFI_PEXPT1_GRST |
+		       SWSYSRST_SGMII1_GRST;
+		regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+
+		/* Assert SGMII reset */
+		regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+		val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
+		       SWSYSRST_XFI_PEXPT1_GRST |
+		       SWSYSRST_SGMII1_GRST;
+		regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+		udelay(100);
+
+		/* De-assert SGMII reset */
+		regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+		val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
+		val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
+			 SWSYSRST_SGMII1_GRST);
+		regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+		/* Disable software reset */
+		regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+		val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
+			 SWSYSRST_SGMII1_GRST);
+		regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+		break;
+	case MTK_GMAC3_ID:
+		/* Enable Software reset */
+		regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+		val |= SWSYSRST_XFI_PEXPT0_GRST |
+		       SWSYSRST_SGMII0_GRST;
+		regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+
+		/* Assert SGMII reset */
+		regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+		val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
+		       SWSYSRST_XFI_PEXPT0_GRST |
+		       SWSYSRST_SGMII0_GRST;
+		regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+		udelay(100);
+
+		/* De-assert SGMII reset */
+		regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+		val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
+		val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
+			 SWSYSRST_SGMII0_GRST);
+		regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+		/* Disable software reset */
+		regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+		val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
+			 SWSYSRST_SGMII0_GRST);
+		regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+		break;
+	}
+
+	mdelay(1);
+}
+
 void mtk_sgmii_setup_phya_gen1(struct mtk_xgmii *ss, int mac_id)
 {
 	u32 id = mtk_mac2xgmii_id(ss->eth, mac_id);
@@ -167,8 +240,10 @@
 	if (!ss->regmap_sgmii[id])
 		return -EINVAL;
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		mtk_xfi_pll_enable(ss);
+		mtk_sgmii_reset(ss, mac_id);
+	}
 
 	/* Assert PHYA power down state */
 	regmap_write(ss->regmap_sgmii[id], SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD);
@@ -222,8 +297,10 @@
 	if (!ss->regmap_sgmii[id])
 		return -EINVAL;
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		mtk_xfi_pll_enable(ss);
+		mtk_sgmii_reset(ss, mac_id);
+	}
 
 	/* Assert PHYA power down state */
 	regmap_write(ss->regmap_sgmii[id], SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
index bdd5231..f4d8db4 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
@@ -312,7 +312,7 @@
 		break;
 	}
 
-	mdelay(1);
+	mdelay(10);
 }
 
 int mtk_usxgmii_setup_mode_an(struct mtk_xgmii *ss, int mac_id, int max_speed)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c
index d2ccecd..796f1cb 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c
@@ -160,8 +160,27 @@
 #define MTK_PHY_RG_DEV1E_REG184		(0x180)
 #define   MTK_PHY_DASN_DAC_IN1_D_MASK	GENMASK(9, 0)
 
+#define MTK_PHY_RG_LP_IIR2_K1_L		(0x22a)
+#define MTK_PHY_RG_LP_IIR2_K1_U		(0x22b)
+#define MTK_PHY_RG_LP_IIR2_K2_L		(0x22c)
+#define MTK_PHY_RG_LP_IIR2_K2_U		(0x22d)
+#define MTK_PHY_RG_LP_IIR2_K3_L		(0x22e)
+#define MTK_PHY_RG_LP_IIR2_K3_U		(0x22f)
+#define MTK_PHY_RG_LP_IIR2_K4_L		(0x230)
+#define MTK_PHY_RG_LP_IIR2_K4_U		(0x231)
+#define MTK_PHY_RG_LP_IIR2_K5_L		(0x232)
+#define MTK_PHY_RG_LP_IIR2_K5_U		(0x233)
+
 #define MTK_PHY_RG_DEV1E_REG234		(0x234)
-#define   MTK_PHY_TR_OPEN_LOOP_EN	GENMASK(0, 0)
+#define   MTK_PHY_TR_OPEN_LOOP_EN_MASK	GENMASK(0, 0)
+#define   MTK_PHY_LPF_X_AVERAGE_MASK	GENMASK(7, 4)
+
+#define MTK_PHY_RG_LPF_CNT_VAL		(0x235)
+
+#define MTK_PHY_RG_DEV1E_REG27C		(0x27c)
+#define   MTK_PHY_VGASTATE_FFE_THR_ST1_MASK	GENMASK(12, 8)
+#define MTK_PHY_RG_DEV1E_REG27D		(0x27d)
+#define   MTK_PHY_VGASTATE_FFE_THR_ST2_MASK	GENMASK(4, 0)
 
 #define MTK_PHY_RG_DEV1E_REG53D		(0x53d)
 #define   MTK_PHY_DA_TX_R50_A_NORMAL_MASK	GENMASK(13, 8)
@@ -488,11 +507,13 @@
 
 static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
 {
+	int i;
 	int bias[16] = {0};
 	switch(phydev->drv->phy_id) {
 		case 0x03a29461:
 		{
-			/* We add some calibration to efuse values:
+			/* We add some calibration to efuse values
+			 * due to board level influence.
 			 * GBE: +7, TBT: +1, HBT: +4, TST: +7
 			 */
 			int tmp[16] = { 7, 1, 4, 7,
@@ -514,6 +535,33 @@
 		default:
 			break;
 	}
+
+	for (i = 0; i < 12; i += 4) {
+		if (likely(buf[i>>2] + bias[i] >= 32)) {
+			bias[i] -= 13;
+		} else {
+			phy_modify_mmd(phydev, MDIO_MMD_VEND1, 0x5c,
+				0xf << (12-i), 0x6 << (12-i));
+			bias[i+1] += 13;
+			bias[i+2] += 13;
+			bias[i+3] += 13;
+		}
+	}
+
+	/* Prevent overflow */
+	for (i = 0; i < 12; i++) {
+		if (buf[i>>2] + bias[i] > 63) {
+			buf[i>>2] = 63;
+			bias[i] = 0;
+		} else if (buf[i>>2] + bias[i] < 0) {
+			/* Bias caused by board design may change in the future.
+			 * So check negative cases, too.
+			 */
+			buf[i>>2] = 0;
+			bias[i] = 0;
+		}
+	}
+
 	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
 		       MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
 	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
@@ -570,6 +618,7 @@
 			      phy_cal_pair_t txg_calen_x)
 {
 	int bias[4] = {0};
+	int i;
 	switch(phydev->drv->phy_id) {
 		case 0x03a29481:
 		{
@@ -582,6 +631,15 @@
 			break;
 	}
 
+	for (i = 0; i < 4; i++) {
+		if (buf[i>>2] + bias[i] > 63) {
+			buf[i>>2] = 63;
+			bias[i] = 0;
+		} else if (buf[i>>2] + bias[i] < 0) {
+			buf[i>>2] = 0;
+			bias[i] = 0;
+		}
+	}
 	switch(txg_calen_x) {
 		case PAIR_A:
 			phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
@@ -885,6 +943,7 @@
 
 static inline void mt7981_phy_finetune(struct phy_device *phydev)
 {
+	u32 i;
 	/* 100M eye finetune:
 	 * Keep middle level of TX MLT3 shapper as default.
 	 * Only change TX MLT3 overshoot level here.
@@ -911,8 +970,83 @@
 	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
 	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
 
+	phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+	/* EnabRandUpdTrig = 1 */
+	__phy_write(phydev, 0x11, 0x2f00);
+	__phy_write(phydev, 0x12, 0xe);
+	__phy_write(phydev, 0x10, 0x8fb0);
+
+	/* SlvDSPreadyTime = 0xc */
+	__phy_write(phydev, 0x11, 0x671);
+	__phy_write(phydev, 0x12, 0xc);
+	__phy_write(phydev, 0x10, 0x8fae);
+
+	/* NormMseLoThresh = 85 */
+	__phy_write(phydev, 0x11, 0x55a0);
+	__phy_write(phydev, 0x12, 0x0);
+	__phy_write(phydev, 0x10, 0x83aa);
+
+	/* InhibitDisableDfeTail1000 = 1 */
+	__phy_write(phydev, 0x11, 0x2b);
+	__phy_write(phydev, 0x12, 0x0);
+	__phy_write(phydev, 0x10, 0x8f80);
+
+	/* SSTr related */
+	__phy_write(phydev, 0x11, 0xbaef);
+	__phy_write(phydev, 0x12, 0x2e);
+	__phy_write(phydev, 0x10, 0x968c);
+
+	/* VcoSlicerThreshBitsHigh */
+	__phy_write(phydev, 0x11, 0x5555);
+	__phy_write(phydev, 0x12, 0x55);
+	__phy_write(phydev, 0x10, 0x8ec0);
+
+	/* ResetSyncOffset = 6 */
+	__phy_write(phydev, 0x11, 0x600);
+	__phy_write(phydev, 0x12, 0x0);
+	__phy_write(phydev, 0x10, 0x8fc0);
+
+	/* VgaDecRate = 1 */
+	__phy_write(phydev, 0x11, 0x4c2a);
+	__phy_write(phydev, 0x12, 0x3e);
+	__phy_write(phydev, 0x10, 0x8fa4);
+
+	phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+	/* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
 	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
-			MTK_PHY_TR_OPEN_LOOP_EN, 0x1);
+		MTK_PHY_TR_OPEN_LOOP_EN_MASK & MTK_PHY_LPF_X_AVERAGE_MASK,
+		BIT(0) & (0x9 << 4));
+
+	/* rg_tr_lpf_cnt_val = 512 */
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
+
+	/* IIR2 related */
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
+
+	/* FFE peaking */
+	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
+		MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
+	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
+		MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
+
+	/* TX shape */
+	/* 10/100/1000 TX shaper is enabled by default */
+	for (i = 0x202; i < 0x230; i += 2) {
+		if (i == 0x20c || i == 0x218 || i == 0x224)
+			continue;
+		phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
+		phy_write_mmd(phydev, MDIO_MMD_VEND2, i+1, 0x23);
+	}
 }
 
 static inline void mt7988_phy_finetune(struct phy_device *phydev)
@@ -933,12 +1067,90 @@
 	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
 			MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
 
-	/* Slave mode finetune, Kp=3/Kf=2 */
 	phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+	/* EnabRandUpdTrig = 1 */
+	__phy_write(phydev, 0x11, 0x2f00);
+	__phy_write(phydev, 0x12, 0xe);
+	__phy_write(phydev, 0x10, 0x8fb0);
+
+	/* SlvDSPreadyTime = 0xc */
+	__phy_write(phydev, 0x11, 0x671);
+	__phy_write(phydev, 0x12, 0xc);
+	__phy_write(phydev, 0x10, 0x8fae);
+
+	/* NormMseLoThresh = 85 */
+	__phy_write(phydev, 0x11, 0x55a0);
 	__phy_write(phydev, 0x12, 0x0);
-	__phy_write(phydev, 0x11, 0x750);
-	__phy_write(phydev, 0x10, 0x9686);
+	__phy_write(phydev, 0x10, 0x83aa);
+
+	/* InhibitDisableDfeTail1000 = 1 */
+	__phy_write(phydev, 0x11, 0x2b);
+	__phy_write(phydev, 0x12, 0x0);
+	__phy_write(phydev, 0x10, 0x8f80);
+
+	/* SSTr related */
+	__phy_write(phydev, 0x11, 0xbaef);
+	__phy_write(phydev, 0x12, 0x2e);
+	__phy_write(phydev, 0x10, 0x968c);
+
+	/* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
+	 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
+	 */
+	__phy_write(phydev, 0x11, 0xd10a);
+	__phy_write(phydev, 0x12, 0x34);
+	__phy_write(phydev, 0x10, 0x8f82);
+
+	/* VcoSlicerThreshBitsHigh */
+	__phy_write(phydev, 0x11, 0x5555);
+	__phy_write(phydev, 0x12, 0x55);
+	__phy_write(phydev, 0x10, 0x8ec0);
+
+	/* ResetSyncOffset = 6 */
+	__phy_write(phydev, 0x11, 0x600);
+	__phy_write(phydev, 0x12, 0x0);
+	__phy_write(phydev, 0x10, 0x8fc0);
+
+	/* VgaDecRate = 1 */
+	__phy_write(phydev, 0x11, 0x4c2a);
+	__phy_write(phydev, 0x12, 0x3e);
+	__phy_write(phydev, 0x10, 0x8fa4);
+
 	phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+	/* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
+	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+		MTK_PHY_TR_OPEN_LOOP_EN_MASK & MTK_PHY_LPF_X_AVERAGE_MASK,
+		BIT(0) & (0x9 << 4));
+
+	/* rg_tr_lpf_cnt_val = 512 */
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
+
+	/* IIR2 related */
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
+
+	/* FFE peaking */
+	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
+		MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
+	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
+		MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
+
+	/* TX shape */
+	/* 10/100/1000 TX shaper is enabled by default */
+	for (i = 0x202; i < 0x230; i += 2) {
+		if (i == 0x20c || i == 0x218 || i == 0x224)
+			continue;
+		phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
+		phy_write_mmd(phydev, MDIO_MMD_VEND2, i+1, 0x23);
+	}
 }
 
 static int mt798x_phy_calibration(struct phy_device *phydev)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
index 9b4cd67..55234b3 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
@@ -3008,15 +3008,6 @@
 index 036fda317..2dfaa1eac 100644
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -22,8 +22,6 @@
- 
- #include "dsa_priv.h"
- 
--static bool dsa_slave_dev_check(const struct net_device *dev);
--
- /* slave mii_bus handling ***************************************************/
- static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg)
- {
 @@ -1033,14 +1031,32 @@ static int dsa_slave_setup_tc_block(struct net_device *dev,
  	}
  }
@@ -3081,12 +3072,8 @@
  };
  
  static struct device_type dsa_type = {
-@@ -1497,10 +1529,11 @@ void dsa_slave_destroy(struct net_device *slave_dev)
- 	free_netdev(slave_dev);
- }
- 
--static bool dsa_slave_dev_check(const struct net_device *dev)
-+bool dsa_slave_dev_check(const struct net_device *dev)
+@@ -1497,7 +1529,8 @@ void dsa_slave_destroy(struct net_device *slave_dev)
+ bool dsa_slave_dev_check(const struct net_device *dev)
  {
  	return dev->netdev_ops == &dsa_slave_netdev_ops;
  }
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0495-mtd-spinand-winbond-Support-for-W25N01KV.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0495-mtd-spinand-winbond-Support-for-W25N01KV.patch
deleted file mode 100644
index f4eb1cd..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0495-mtd-spinand-winbond-Support-for-W25N01KV.patch
+++ /dev/null
@@ -1,76 +0,0 @@
---- a/drivers/mtd/nand/spi/Kconfig	2022-11-28 18:40:18.994239565 +0800
-+++ b/drivers/mtd/nand/spi/Kconfig	2022-11-28 18:39:50.477971561 +0800
-@@ -7,11 +7,3 @@ menuconfig MTD_SPI_NAND
- 	help
- 	  This is the framework for the SPI NAND device drivers.
- 
--config MTD_SPI_NAND_W25N01KV
--	tristate "Winbond W25N01KV Support"
--	select MTD_SPI_NAND
--	default n
--	help
--	  Winbond W25N01KV share the same ID with W25N01GV. However, they have
--	  different attributes.
--
-diff -uprN a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
---- a/drivers/mtd/nand/spi/winbond.c	2022-11-28 18:40:18.994239565 +0800
-+++ b/drivers/mtd/nand/spi/winbond.c	2022-11-28 18:39:50.477971561 +0800
-@@ -26,13 +26,11 @@
- #define W25N01_M02GV_STATUS_ECC_1_BITFLIPS	(1 << 4)
- #define W25N01_M02GV_STATUS_ECC_UNCOR_ERROR	(2 << 4)
- 
--#if IS_ENABLED(CONFIG_MTD_SPI_NAND_W25N01KV)
- #define W25N01KV_STATUS_ECC_MASK		(3 << 4)
- #define W25N01KV_STATUS_ECC_NO_BITFLIPS		(0 << 4)
- #define W25N01KV_STATUS_ECC_1_3_BITFLIPS	(1 << 4)
- #define W25N01KV_STATUS_ECC_4_BITFLIPS		(3 << 4)
- #define W25N01KV_STATUS_ECC_UNCOR_ERROR		(2 << 4)
--#endif
- 
- static SPINAND_OP_VARIANTS(read_cache_variants,
- 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
-@@ -116,7 +114,6 @@ static int w25m02gv_select_target(struct
- 	return spi_mem_exec_op(spinand->spimem, &op);
- }
- 
--#if IS_ENABLED(CONFIG_MTD_SPI_NAND_W25N01KV)
- static int w25n01kv_ecc_get_status(struct spinand_device *spinand,
- 					u8 status)
- {
-@@ -139,7 +136,6 @@ static int w25n01kv_ecc_get_status(struc
- 
- 	return -EINVAL;
- }
--#endif
- 
- static int w25n02kv_n04kv_ecc_get_status(struct spinand_device *spinand,
- 					u8 status)
-@@ -181,10 +177,9 @@ static const struct spinand_info winbond
- 		     0,
- 		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
- 		     SPINAND_SELECT_TARGET(w25m02gv_select_target)),
--#if IS_ENABLED(CONFIG_MTD_SPI_NAND_W25N01KV)
- 	SPINAND_INFO("W25N01KV",
--		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
--		     NAND_MEMORG(1, 2048, 96, 64, 1024, 20, 1, 1, 1),
-+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
-+		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
- 		     NAND_ECCREQ(4, 512),
- 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
- 					      &write_cache_variants,
-@@ -192,7 +187,6 @@ static const struct spinand_info winbond
- 		     0,
- 		     SPINAND_ECCINFO(&w25n02kv_n04kv_ooblayout,
- 				     w25n01kv_ecc_get_status)),
--#else
- 	SPINAND_INFO("W25N01GV",
- 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
- 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-@@ -202,7 +196,6 @@ static const struct spinand_info winbond
- 					      &update_cache_variants),
- 		     0,
- 		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
--#endif
- 	SPINAND_INFO("W25N02KV",
- 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
- 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch
index 888d5cb..dbba2f6 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch
@@ -12,7 +12,7 @@
 
 --- a/drivers/net/dsa/b53/b53_common.c
 +++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1284,7 +1284,9 @@ EXPORT_SYMBOL(b53_phylink_mac_link_down)
+@@ -1312,7 +1312,9 @@ EXPORT_SYMBOL(b53_phylink_mac_link_down)
  void b53_phylink_mac_link_up(struct dsa_switch *ds, int port,
  			     unsigned int mode,
  			     phy_interface_t interface,
@@ -25,7 +25,7 @@
  
 --- a/drivers/net/dsa/b53/b53_priv.h
 +++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -337,7 +337,9 @@ void b53_phylink_mac_link_down(struct ds
+@@ -344,7 +344,9 @@ void b53_phylink_mac_link_down(struct ds
  void b53_phylink_mac_link_up(struct dsa_switch *ds, int port,
  			     unsigned int mode,
  			     phy_interface_t interface,
@@ -38,7 +38,7 @@
  		     const struct switchdev_obj_port_vlan *vlan);
 --- a/drivers/net/dsa/bcm_sf2.c
 +++ b/drivers/net/dsa/bcm_sf2.c
-@@ -641,7 +641,9 @@ static void bcm_sf2_sw_mac_link_down(str
+@@ -661,7 +661,9 @@ static void bcm_sf2_sw_mac_link_down(str
  static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
  				   unsigned int mode,
  				   phy_interface_t interface,
@@ -51,7 +51,7 @@
  	struct ethtool_eee *p = &priv->dev->ports[port].eee;
 --- a/drivers/net/dsa/lantiq_gswip.c
 +++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1661,7 +1661,9 @@ static void gswip_phylink_mac_link_down(
+@@ -1662,7 +1662,9 @@ static void gswip_phylink_mac_link_down(
  static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port,
  				      unsigned int mode,
  				      phy_interface_t interface,
@@ -64,7 +64,7 @@
  
 --- a/drivers/net/dsa/mt7530.c
 +++ b/drivers/net/dsa/mt7530.c
-@@ -1440,7 +1440,9 @@ static void mt7530_phylink_mac_link_down
+@@ -1441,7 +1441,9 @@ static void mt7530_phylink_mac_link_down
  static void mt7530_phylink_mac_link_up(struct dsa_switch *ds, int port,
  				       unsigned int mode,
  				       phy_interface_t interface,
@@ -103,7 +103,7 @@
  }
 --- a/include/net/dsa.h
 +++ b/include/net/dsa.h
-@@ -406,7 +406,9 @@ struct dsa_switch_ops {
+@@ -407,7 +407,9 @@ struct dsa_switch_ops {
  	void	(*phylink_mac_link_up)(struct dsa_switch *ds, int port,
  				       unsigned int mode,
  				       phy_interface_t interface,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch
index 23fba85..57066a3 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch
@@ -51,7 +51,7 @@
  
  	mutex_unlock(&priv->reg_mutex);
  }
-@@ -1395,8 +1384,7 @@ static void mt7530_phylink_mac_config(st
+@@ -1396,8 +1385,7 @@ static void mt7530_phylink_mac_config(st
  
  	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
  	mcr_new = mcr_cur;
@@ -61,7 +61,7 @@
  	mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
  		   PMCR_BACKPR_EN | PMCR_FORCE_MODE;
  
-@@ -1404,26 +1392,6 @@ static void mt7530_phylink_mac_config(st
+@@ -1405,26 +1393,6 @@ static void mt7530_phylink_mac_config(st
  	if (port == 5 && dsa_is_user_port(ds, 5))
  		mcr_new |= PMCR_EXT_PHY;
  
@@ -88,7 +88,7 @@
  	if (mcr_new != mcr_cur)
  		mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
  }
-@@ -1434,7 +1402,7 @@ static void mt7530_phylink_mac_link_down
+@@ -1435,7 +1403,7 @@ static void mt7530_phylink_mac_link_down
  {
  	struct mt7530_priv *priv = ds->priv;
  
@@ -97,7 +97,7 @@
  }
  
  static void mt7530_phylink_mac_link_up(struct dsa_switch *ds, int port,
-@@ -1445,8 +1413,31 @@ static void mt7530_phylink_mac_link_up(s
+@@ -1446,8 +1414,31 @@ static void mt7530_phylink_mac_link_up(s
  				       bool tx_pause, bool rx_pause)
  {
  	struct mt7530_priv *priv = ds->priv;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch
index 718ed8e..84579ac 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch
@@ -47,7 +47,7 @@
  		return -EINVAL;
  	}
  
-@@ -1332,12 +1334,11 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -1333,12 +1335,11 @@ mt7530_setup(struct dsa_switch *ds)
  	return 0;
  }
  
@@ -63,7 +63,7 @@
  
  	switch (port) {
  	case 0: /* Internal phy */
-@@ -1346,33 +1347,114 @@ static void mt7530_phylink_mac_config(st
+@@ -1347,33 +1348,114 @@ static void mt7530_phylink_mac_config(st
  	case 3:
  	case 4:
  		if (state->interface != PHY_INTERFACE_MODE_GMII)
@@ -189,7 +189,7 @@
  		return;
  	}
  
-@@ -1440,61 +1522,44 @@ static void mt7530_phylink_mac_link_up(s
+@@ -1441,61 +1523,44 @@ static void mt7530_phylink_mac_link_up(s
  	mt7530_set(priv, MT7530_PMCR_P(port), mcr);
  }
  
@@ -274,7 +274,7 @@
  	phylink_set(mask, Pause);
  	phylink_set(mask, Asym_Pause);
  
-@@ -1590,12 +1655,45 @@ static int mt7530_set_mac_eee(struct dsa
+@@ -1591,12 +1656,45 @@ static int mt7530_set_mac_eee(struct dsa
  	return 0;
  }
  
@@ -323,7 +323,7 @@
  	.get_ethtool_stats	= mt7530_get_ethtool_stats,
  	.get_sset_count		= mt7530_get_sset_count,
  	.port_enable		= mt7530_port_enable,
-@@ -1612,18 +1710,43 @@ static const struct dsa_switch_ops mt753
+@@ -1613,18 +1711,43 @@ static const struct dsa_switch_ops mt753
  	.port_vlan_del		= mt7530_port_vlan_del,
  	.port_mirror_add	= mt7530_port_mirror_add,
  	.port_mirror_del	= mt7530_port_mirror_del,
@@ -372,7 +372,7 @@
  	{ /* sentinel */ },
  };
  MODULE_DEVICE_TABLE(of, mt7530_of_match);
-@@ -1661,8 +1784,21 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -1662,8 +1785,21 @@ mt7530_probe(struct mdio_device *mdiodev
  	/* Get the hardware identifier from the devicetree node.
  	 * We will need it for some of the clock and regulator setup.
  	 */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch
index 8ede862..95dddf6 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch
@@ -466,7 +466,7 @@
  	}
  }
  
-@@ -1280,7 +1619,7 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -1281,7 +1620,7 @@ mt7530_setup(struct dsa_switch *ds)
  			   PCR_MATRIX_CLR);
  
  		if (dsa_is_cpu_port(ds, i))
@@ -475,7 +475,7 @@
  		else
  			mt7530_port_disable(ds, i);
  
-@@ -1334,6 +1673,118 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -1335,6 +1674,118 @@ mt7530_setup(struct dsa_switch *ds)
  	return 0;
  }
  
@@ -594,7 +594,7 @@
  static bool
  mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
  			  const struct phylink_link_state *state)
-@@ -1372,6 +1823,47 @@ unsupported:
+@@ -1373,6 +1824,47 @@ unsupported:
  	return false;
  }
  
@@ -642,7 +642,7 @@
  static bool
  mt753x_phy_mode_supported(struct dsa_switch *ds, int port,
  			  const struct phylink_link_state *state)
-@@ -1404,6 +1896,227 @@ mt7530_mac_config(struct dsa_switch *ds,
+@@ -1405,6 +1897,227 @@ mt7530_mac_config(struct dsa_switch *ds,
  	return 0;
  }
  
@@ -870,7 +870,7 @@
  static int
  mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
  		  const struct phylink_link_state *state)
-@@ -1439,6 +2152,8 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -1440,6 +2153,8 @@ mt753x_phylink_mac_config(struct dsa_swi
  		if (mt753x_mac_config(ds, port, mode, state) < 0)
  			goto unsupported;
  
@@ -879,7 +879,7 @@
  		break;
  	case 6: /* 1st cpu port */
  		if (priv->p6_interface == state->interface)
-@@ -1458,7 +2173,8 @@ unsupported:
+@@ -1459,7 +2174,8 @@ unsupported:
  		return;
  	}
  
@@ -889,7 +889,7 @@
  		dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
  			__func__);
  		return;
-@@ -1468,7 +2184,7 @@ unsupported:
+@@ -1469,7 +2185,7 @@ unsupported:
  	mcr_new = mcr_cur;
  	mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
  	mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
@@ -898,7 +898,7 @@
  
  	/* Are we connected to external phy */
  	if (port == 5 && dsa_is_user_port(ds, 5))
-@@ -1478,7 +2194,18 @@ unsupported:
+@@ -1479,7 +2195,18 @@ unsupported:
  		mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
  }
  
@@ -918,7 +918,7 @@
  					 unsigned int mode,
  					 phy_interface_t interface)
  {
-@@ -1487,7 +2214,19 @@ static void mt7530_phylink_mac_link_down
+@@ -1488,7 +2215,19 @@ static void mt7530_phylink_mac_link_down
  	mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
  }
  
@@ -939,7 +939,7 @@
  				       unsigned int mode,
  				       phy_interface_t interface,
  				       struct phy_device *phydev,
-@@ -1497,18 +2236,29 @@ static void mt7530_phylink_mac_link_up(s
+@@ -1498,18 +2237,29 @@ static void mt7530_phylink_mac_link_up(s
  	struct mt7530_priv *priv = ds->priv;
  	u32 mcr;
  
@@ -971,7 +971,7 @@
  		break;
  	}
  	if (duplex == DUPLEX_FULL) {
-@@ -1522,6 +2272,45 @@ static void mt7530_phylink_mac_link_up(s
+@@ -1523,6 +2273,45 @@ static void mt7530_phylink_mac_link_up(s
  	mt7530_set(priv, MT7530_PMCR_P(port), mcr);
  }
  
@@ -1017,7 +1017,7 @@
  static void
  mt7530_mac_port_validate(struct dsa_switch *ds, int port,
  			 unsigned long *supported)
-@@ -1530,6 +2319,14 @@ mt7530_mac_port_validate(struct dsa_swit
+@@ -1531,6 +2320,14 @@ mt7530_mac_port_validate(struct dsa_swit
  		phylink_set(supported, 1000baseX_Full);
  }
  
@@ -1032,7 +1032,7 @@
  static void
  mt753x_phylink_validate(struct dsa_switch *ds, int port,
  			unsigned long *supported,
-@@ -1546,7 +2343,8 @@ mt753x_phylink_validate(struct dsa_switc
+@@ -1547,7 +2344,8 @@ mt753x_phylink_validate(struct dsa_switc
  
  	phylink_set_port_modes(mask);
  
@@ -1042,7 +1042,7 @@
  		phylink_set(mask, 10baseT_Half);
  		phylink_set(mask, 10baseT_Full);
  		phylink_set(mask, 100baseT_Half);
-@@ -1565,6 +2363,11 @@ mt753x_phylink_validate(struct dsa_switc
+@@ -1566,6 +2364,11 @@ mt753x_phylink_validate(struct dsa_switc
  
  	linkmode_and(supported, supported, mask);
  	linkmode_and(state->advertising, state->advertising, mask);
@@ -1054,7 +1054,7 @@
  }
  
  static int
-@@ -1655,6 +2458,63 @@ static int mt7530_set_mac_eee(struct dsa
+@@ -1656,6 +2459,63 @@ static int mt7530_set_mac_eee(struct dsa
  	return 0;
  }
  
@@ -1118,7 +1118,7 @@
  static int
  mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port,
  			      struct phylink_link_state *state)
-@@ -1708,13 +2568,14 @@ static const struct dsa_switch_ops mt753
+@@ -1709,13 +2569,14 @@ static const struct dsa_switch_ops mt753
  	.port_vlan_prepare	= mt7530_port_vlan_prepare,
  	.port_vlan_add		= mt7530_port_vlan_add,
  	.port_vlan_del		= mt7530_port_vlan_del,
@@ -1137,7 +1137,7 @@
  	.get_mac_eee		= mt7530_get_mac_eee,
  	.set_mac_eee		= mt7530_set_mac_eee,
  };
-@@ -1742,11 +2603,26 @@ static const struct mt753x_info mt753x_t
+@@ -1743,11 +2604,26 @@ static const struct mt753x_info mt753x_t
  		.mac_port_get_state = mt7530_phylink_mac_link_state,
  		.mac_port_config = mt7530_mac_config,
  	},
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
index 1ed206c..b31b40d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
@@ -142,7 +142,7 @@
 index 0000000..7aeec86
 --- /dev/null
 +++ b/drivers/net/phy/aquantia_firmware.c
-@@ -0,0 +1,995 @@
+@@ -0,0 +1,1023 @@
 +// SPDX-License-Identifier: GPL-2.0
 +/* FW download driver for Aquantia PHY
 + */
@@ -977,11 +977,22 @@
 +	int j;
 +
 +	for (j = 0; j < num_phydevs; j++) {
++		/* stall the uP */
++		val = phy_read_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_CONTROL2);
++		val |= VEND1_CONTROL2_UP_RUNSTALL_OVERRIDE;
++		val |= VEND1_CONTROL2_UP_RUNSTALL;
++		phy_write_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_CONTROL2, val);
++
 +		/* disable the S/W reset to the Global MMD registers */
 +		val = phy_read_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_RESET_CONTROL);
 +		val |= VEND1_RESET_CONTROL_MMD_RESET_DISABLE;
 +		phy_write_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_RESET_CONTROL, val);
 +
++		/* de-assert Global S/W reset */
++		val = phy_read_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_STD_CONTROL1);
++		val &= ~VEND1_STD_CONTROL1_SOFT_RESET;
++		phy_write_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_STD_CONTROL1, val);
++
 +		/* assert Global S/W reset */
 +		val = phy_read_mmd(phydevs[j], MDIO_MMD_VEND1, VEND1_STD_CONTROL1);
 +		val |= VEND1_STD_CONTROL1_SOFT_RESET;
@@ -1018,6 +1029,11 @@
 +	if (!fw)
 +		return;
 +
++	for (i = 0; i < MAX_GANGLOAD_DEVICES; i++) {
++		if (phy_is_started(phydevs[i]))
++			phy_stop(phydevs[i]);
++	}
++
 +retry:
 +	memset(result, 0, sizeof(result));
 +
@@ -1042,9 +1058,13 @@
 +		if (result[i] == 0) {
 +			priv = phydevs[i]->priv;
 +			priv->fw_initialized = true;
++
 +#ifdef CONFIG_AQUANTIA_PHY_MDI_SWAP
 +			aqr107_config_mdi(phydevs[i]);
 +#endif
++
++			if (!phy_is_started(phydevs[i]))
++				phy_start(phydevs[i]);
 +		}
 +	}
 +
@@ -1104,6 +1124,7 @@
 +{
 +	struct aqr107_priv *priv = phydev->priv;
 +	struct device *dev = &phydev->mdio.dev;
++	int i;
 +
 +	if (priv->fw_initialized == true)
 +		return 0;
@@ -1122,6 +1143,13 @@
 +		wake_up_process(gangload_kthread);
 +	}
 +
++	for (i = 0; i < gangload; i++) {
++		if (gangload_phydevs[i] == phydev) {
++			dev_err(dev, "Detect duplicate gangload phydev\n");
++			return -EINVAL;
++		}
++	}
++
 +	gangload_phydevs[gangload] = phydev;
 +	gangload++;
 +
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/753-net-mt753x-phy-coverity-scan.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/753-net-mt753x-phy-coverity-scan.patch
new file mode 100755
index 0000000..bc1bf03
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/753-net-mt753x-phy-coverity-scan.patch
@@ -0,0 +1,206 @@
+diff -Naur a/drivers/net/phy/mtk/mt753x/mt7531.c b/drivers/net/phy/mtk/mt753x/mt7531.c
+--- a/drivers/net/phy/mtk/mt753x/mt7531.c	2022-11-25 14:11:51.944272549 +0800
++++ b/drivers/net/phy/mtk/mt753x/mt7531.c	2022-11-25 14:19:49.970820719 +0800
+@@ -1062,6 +1062,7 @@
+ 	u32 pmcr;
+ 	u32 speed;
+ 
++	pdev = container_of(gsw->dev, struct platform_device, dev);
+ 	switch_node = of_find_node_by_name(NULL, "switch0");
+ 	if (switch_node == NULL) {
+ 		dev_err(&pdev->dev, "switch node invaild\n");
+@@ -1074,7 +1075,6 @@
+ 		return -EIO;
+ 	}
+ 
+-	pdev = container_of(gsw->dev, struct platform_device, dev);
+ 	gsw->sysctrl_base = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+ 							"mediatek,sysctrl");
+ 	if (IS_ERR(gsw->sysctrl_base)) {
+diff -Naur a/drivers/net/phy/mtk/mt753x/mt753x_common.c b/drivers/net/phy/mtk/mt753x/mt753x_common.c
+--- a/drivers/net/phy/mtk/mt753x/mt753x_common.c	2022-11-25 14:12:06.308223474 +0800
++++ b/drivers/net/phy/mtk/mt753x/mt753x_common.c	2022-11-25 14:21:52.038450276 +0800
+@@ -49,6 +49,9 @@
+ 	case MAC_SPD_2500:
+ 		speed = "2.5Gbps";
+ 		break;
++	default:
++		dev_info(gsw->dev, "Invalid speed\n");
++		return;
+ 	}
+ 
+ 	if (pmsr & MAC_LNK_STS) {
+diff -Naur a/drivers/net/phy/mtk/mt753x/mt753x_mdio.c b/drivers/net/phy/mtk/mt753x/mt753x_mdio.c
+--- a/drivers/net/phy/mtk/mt753x/mt753x_mdio.c	2022-11-25 14:12:29.064162894 +0800
++++ b/drivers/net/phy/mtk/mt753x/mt753x_mdio.c	2022-11-25 17:04:01.973949052 +0800
+@@ -495,7 +495,7 @@
+ 	struct device_node *np = gsw->dev->of_node;
+ 	struct reset_control *rstc;
+ 	int mcm;
+-	int ret = -EINVAL;
++	int ret;
+ 
+ 	mcm = of_property_read_bool(np, "mediatek,mcm");
+ 	if (mcm) {
+diff -Naur a/drivers/net/phy/mtk/mt753x/mt753x_nl.c b/drivers/net/phy/mtk/mt753x/mt753x_nl.c
+--- a/drivers/net/phy/mtk/mt753x/mt753x_nl.c	2022-11-25 14:12:12.292202033 +0800
++++ b/drivers/net/phy/mtk/mt753x/mt753x_nl.c	2022-11-25 17:01:26.881930912 +0800
+@@ -75,8 +75,10 @@
+ 		len = snprintf(buf, sizeof(buf),
+ 			       "id: %d, model: %s, node: %s\n",
+ 			       gsw->id, gsw->name, gsw->dev->of_node->name);
+-		strncat(buff, buf, size - total);
+-		total += len;
++		if (len == strlen(buf)) {
++			strncat(buff, buf, size - total);
++			total += len;
++		}
+ 	}
+ 
+ 	mt753x_put_gsw();
+diff -Naur a/drivers/net/phy/mtk/mt753x/mt753x_phy.c b/drivers/net/phy/mtk/mt753x/mt753x_phy.c
+--- a/drivers/net/phy/mtk/mt753x/mt753x_phy.c	2022-11-25 14:12:34.160149995 +0800
++++ b/drivers/net/phy/mtk/mt753x/mt753x_phy.c	2022-11-29 14:12:28.261884707 +0800
+@@ -141,7 +141,7 @@
+ 	u16 dev1e_17a_tmp, dev1e_e0_tmp;
+ 
+ 	/* *** Iext/Rext Cal start ************ */
+-	all_ana_cal_status = ANACAL_INIT;
++	//all_ana_cal_status = ANACAL_INIT;
+ 	/* analog calibration enable, Rext calibration enable */
+ 	/* 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a */
+ 	/* 1e_dc[0]:rg_txvos_calen */
+@@ -185,7 +185,7 @@
+ 			all_ana_cal_status = ANACAL_FINISH;
+ 			//printk("  GE Rext AnaCal Done! (%d)(0x%x)  \r\n", cnt, rg_zcal_ctrl);
+ 		} else {
+-			dev1e_17a_tmp = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x017a);
++			//dev1e_17a_tmp = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x017a);
+ 			dev1e_e0_tmp =	tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0xe0);
+ 			if ((rg_zcal_ctrl == 0x3F) || (rg_zcal_ctrl == 0x00)) {
+ 				all_ana_cal_status = ANACAL_SATURATION;  /* need to FT(IC fail?) */
+@@ -580,33 +580,35 @@
+ 				} else if (phyaddr == 1) {
+ 					if (calibration_pair == ANACAL_PAIR_A)
+ 						tx_amp_temp = tx_amp_temp - 1;
+-					else if(calibration_pair == ANACAL_PAIR_B)
+-						tx_amp_temp = tx_amp_temp ;
++					//else if(calibration_pair == ANACAL_PAIR_B)
++					//	tx_amp_temp = tx_amp_temp;
+ 					else if(calibration_pair == ANACAL_PAIR_C)
+ 						tx_amp_temp = tx_amp_temp - 1;
+ 					else if(calibration_pair == ANACAL_PAIR_D)
+ 						tx_amp_temp = tx_amp_temp - 1;
+ 				} else if (phyaddr == 2) {
+-					if (calibration_pair == ANACAL_PAIR_A)
+-						tx_amp_temp = tx_amp_temp;
+-					else if(calibration_pair == ANACAL_PAIR_B)
++					//if (calibration_pair == ANACAL_PAIR_A)
++					//	tx_amp_temp = tx_amp_temp;
++					//else if(calibration_pair == ANACAL_PAIR_B)
++					if(calibration_pair == ANACAL_PAIR_B)
+ 						tx_amp_temp = tx_amp_temp - 1;
+-					else if(calibration_pair == ANACAL_PAIR_C)
+-						tx_amp_temp = tx_amp_temp;
++					//else if(calibration_pair == ANACAL_PAIR_C)
++					//	tx_amp_temp = tx_amp_temp;
+ 					else if(calibration_pair == ANACAL_PAIR_D)
+ 						tx_amp_temp = tx_amp_temp - 1;
+-				} else if (phyaddr == 3) {
+-					tx_amp_temp = tx_amp_temp;
++				//} else if (phyaddr == 3) {
++				//	tx_amp_temp = tx_amp_temp;
+ 				} else if (phyaddr == 4) {
+-					if (calibration_pair == ANACAL_PAIR_A)
+-						tx_amp_temp = tx_amp_temp;
+-					else if(calibration_pair == ANACAL_PAIR_B)
++					//if (calibration_pair == ANACAL_PAIR_A)
++					//	tx_amp_temp = tx_amp_temp;
++					//else if(calibration_pair == ANACAL_PAIR_B)
++					if(calibration_pair == ANACAL_PAIR_B)
+ 						tx_amp_temp = tx_amp_temp - 1;
+-					else if(calibration_pair == ANACAL_PAIR_C)
+-						tx_amp_temp = tx_amp_temp;
+-					else if(calibration_pair == ANACAL_PAIR_D)
+-						tx_amp_temp = tx_amp_temp;
+-				}								
++					//else if(calibration_pair == ANACAL_PAIR_C)
++					//	tx_amp_temp = tx_amp_temp;
++					//else if(calibration_pair == ANACAL_PAIR_D)
++					//	tx_amp_temp = tx_amp_temp;
++				}
+ 				reg_temp = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, tx_amp_reg)&(~0xff00);
+ 				tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((tx_amp_temp)<<tx_amp_reg_shift)));
+ 				tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, tx_amp_reg, (tx_amp_temp|((tx_amp_temp)<<tx_amp_reg_shift)));
+@@ -704,7 +706,7 @@
+                                        reg_backup = 0x0000;
+                                        reg_backup |= ((reg_tmp << 10) | (reg_tmp << 0));
+ 					tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x12, reg_backup);
+-					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x12);
++					//reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x12);
+ 					//printk("PORT[%d] 1e.012 = %x (OFFSET_1000M_PAIR_A)\n", phyaddr, reg_backup);
+ 					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x16);
+ 					reg_tmp = ((reg_backup & 0x3f) >> 0);
+@@ -712,7 +714,7 @@
+ 					reg_backup = (reg_backup & (~0x3f));
+ 					reg_backup |= (reg_tmp << 0);
+ 					tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x16, reg_backup);
+-					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x16);
++					//reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x16);
+ 					//printk("PORT[%d] 1e.016 = %x (OFFSET_TESTMODE_1000M_PAIR_A)\n", phyaddr, reg_backup);
+ 				}
+ 				else if(calibration_pair == ANACAL_PAIR_B){
+@@ -722,7 +724,7 @@
+                                        reg_backup = 0x0000;
+                                        reg_backup |= ((reg_tmp << 8) | (reg_tmp << 0));
+ 					tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x17, reg_backup);
+-					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x17);
++					//reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x17);
+ 					//printk("PORT[%d] 1e.017 = %x (OFFSET_1000M_PAIR_B)\n", phyaddr, reg_backup);
+ 					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x18);
+ 					reg_tmp = ((reg_backup & 0x3f) >> 0);
+@@ -730,7 +732,7 @@
+ 					reg_backup = (reg_backup & (~0x3f));
+ 					reg_backup |= (reg_tmp << 0);
+ 					tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x18, reg_backup);
+-					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x18);
++					//reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x18);
+ 					//printk("PORT[%d] 1e.018 = %x (OFFSET_TESTMODE_1000M_PAIR_B)\n", phyaddr, reg_backup);
+ 				}
+ 				else if(calibration_pair == ANACAL_PAIR_C){
+@@ -740,7 +742,7 @@
+ 					reg_backup = (reg_backup & (~0x3f00));
+ 					reg_backup |= (reg_tmp << 8);
+ 					tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x19, reg_backup);
+-					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x19);
++					//reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x19);
+ 					//printk("PORT[%d] 1e.019 = %x (OFFSET_1000M_PAIR_C)\n", phyaddr, reg_backup);
+ 					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x20);
+ 					reg_tmp = ((reg_backup & 0x3f) >> 0);
+@@ -748,7 +750,7 @@
+ 					reg_backup = (reg_backup & (~0x3f));
+ 					reg_backup |= (reg_tmp << 0);
+ 					tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x20, reg_backup);
+-					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x20);
++					//reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x20);
+ 					//printk("PORT[%d] 1e.020 = %x (OFFSET_TESTMODE_1000M_PAIR_C)\n", phyaddr, reg_backup);
+ 				}
+ 				else if(calibration_pair == ANACAL_PAIR_D){
+@@ -758,7 +760,7 @@
+ 					reg_backup = (reg_backup & (~0x3f00));
+ 					reg_backup |= (reg_tmp << 8);
+ 					tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x21, reg_backup);
+-					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x21);
++					//reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x21);
+ 					//printk("PORT[%d] 1e.021 = %x (OFFSET_1000M_PAIR_D)\n", phyaddr, reg_backup);
+ 					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x22);
+ 					reg_tmp = ((reg_backup & 0x3f) >> 0);
+@@ -766,7 +768,7 @@
+ 					reg_backup = (reg_backup & (~0x3f));
+ 					reg_backup |= (reg_tmp << 0);
+ 					tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x22, reg_backup);
+-					reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x22);
++					//reg_backup = tc_phy_read_dev_reg(gsw,  phyaddr, 0x1e, 0x22);
+ 					//printk("PORT[%d] 1e.022 = %x (OFFSET_TESTMODE_1000M_PAIR_D)\n", phyaddr, reg_backup);
+ 				}
+ 
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
index 1634496..2de6831 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
@@ -36,7 +36,6 @@
     file://0402-sound-add-mt7986-driver.patch \
     file://0490-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch \
     file://0491-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch \
-    file://0495-mtd-spinand-winbond-Support-for-W25N01KV.patch \
     file://0500-v5.6-crypto-backport-inside-secure.patch \
     file://0501-crypto-add-eip97-inside-secure-support.patch \
     file://0502-dts-mt7623-eip97-inside-secure-support.patch \
@@ -115,6 +114,7 @@
     file://750-add-mdio-bus-for-gphy-calibration.patch \
     file://751-net-phy-aquantia-add-firmware-download.patch \
     file://752-net-dsa-phy-coverity-scan.patch \
+    file://753-net-mt753x-phy-coverity-scan.patch \
     file://8000-PATCH-1-4-tphy-support-type-switch-by-pericfg.patch \
     file://8001-PATCH-2-4-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch \
     file://8002-PATCH-3-4-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch \
diff --git a/recipes-kernel/linux/linux-mediatek_5.4.bb b/recipes-kernel/linux/linux-mediatek_5.4.bb
index 583f5d5..76f9a56 100644
--- a/recipes-kernel/linux/linux-mediatek_5.4.bb
+++ b/recipes-kernel/linux/linux-mediatek_5.4.bb
@@ -56,6 +56,7 @@
 SRC_URI_remove = " \
     file://738-mt7531-gsw-internal_phy_calibration.patch \
     file://739-mt7531-gsw-port5_external_phy_init.patch \
+    file://753-net-mt753x-phy-coverity-scan.patch \
     "
 SRC_URI_remove_mt7986-32bit = " \
     file://401-pinctrl-add-mt7986-driver.patch \