diff --git a/target/linux/ath79/patches-5.10/600-of_net-add-mac-address-ascii-support.patch b/target/linux/ath79/patches-5.10/600-of_net-add-mac-address-ascii-support.patch
new file mode 100644
index 0000000000..8849afb4d6
--- /dev/null
+++ b/target/linux/ath79/patches-5.10/600-of_net-add-mac-address-ascii-support.patch
@@ -0,0 +1,103 @@
+Index: linux-5.15.31/net/ethernet/eth.c
+===================================================================
+--- linux-5.15.31.orig/net/ethernet/eth.c
++++ linux-5.15.31/net/ethernet/eth.c
+@@ -544,6 +544,63 @@ int eth_platform_get_mac_address(struct
+ }
+ EXPORT_SYMBOL(eth_platform_get_mac_address);
+ 
++static void *nvmem_cell_get_mac_address(struct nvmem_cell *cell)
++{
++	size_t len;
++	void *mac;
++
++	mac = nvmem_cell_read(cell, &len);
++	if (IS_ERR(mac))
++		return PTR_ERR(mac);
++	if (len != ETH_ALEN) {
++		kfree(mac);
++		return ERR_PTR(-EINVAL);
++	}
++	return mac;
++}
++
++static void *nvmem_cell_get_mac_address_ascii(struct nvmem_cell *cell)
++{
++	size_t len;
++	int ret;
++	void *mac_ascii;
++	u8 *mac;
++
++	mac_ascii = nvmem_cell_read(cell, &len);
++	if (IS_ERR(mac_ascii))
++		return PTR_ERR(mac_ascii);
++	if (len != ETH_ALEN*2+5) {
++		kfree(mac_ascii);
++		return ERR_PTR(-EINVAL);
++	}
++	mac = kmalloc(ETH_ALEN, GFP_KERNEL);
++	if (!mac) {
++		kfree(mac_ascii);
++		return ERR_PTR(-ENOMEM);
++	}
++	ret = sscanf(mac_ascii, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
++				&mac[0], &mac[1], &mac[2],
++				&mac[3], &mac[4], &mac[5]);
++	kfree(mac_ascii);
++	if (ret == ETH_ALEN)
++		return mac;
++	kfree(mac);
++	return ERR_PTR(-EINVAL);
++}
++
++static struct nvmem_cell_mac_address_property {
++	char *name;
++	void *(*read)(struct nvmem_cell *);
++} nvmem_cell_mac_address_properties[] = {
++	{
++		.name = "mac-address",
++		.read = nvmem_cell_get_mac_address,
++	}, {
++		.name = "mac-address-ascii",
++		.read = nvmem_cell_get_mac_address_ascii,
++	},
++};
++
+ /**
+  * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
+  * 'mac-address' associated with given device.
+@@ -557,19 +614,23 @@ int nvmem_get_mac_address(struct device
+ {
+ 	struct nvmem_cell *cell;
+ 	const void *mac;
+-	size_t len;
++	struct nvmem_cell_mac_address_property *property;
++	int i;
+ 
+-	cell = nvmem_cell_get(dev, "mac-address");
+-	if (IS_ERR(cell))
+-		return PTR_ERR(cell);
+-
+-	mac = nvmem_cell_read(cell, &len);
+-	nvmem_cell_put(cell);
+-
+-	if (IS_ERR(mac))
+-		return PTR_ERR(mac);
++	for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
++		property = &nvmem_cell_mac_address_properties[i];
++		cell = nvmem_cell_get(dev, property->name);
++		if (IS_ERR(cell)) {
++			if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1)
++				return PTR_ERR(cell);
++			continue;
++		}
++		mac = property->read(cell);
++		nvmem_cell_put(cell);
++		break;
++	}
+ 
+-	if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
++	if (!is_valid_ether_addr(mac)) {
+ 		kfree(mac);
+ 		return -EINVAL;
+ 	}
diff --git a/target/linux/ath79/patches-5.15/408-mtd-redboot_partition_scan.patch b/target/linux/ath79/patches-5.15/408-mtd-redboot_partition_scan.patch
index 905c1319db..07c0a258ae 100644
--- a/target/linux/ath79/patches-5.15/408-mtd-redboot_partition_scan.patch
+++ b/target/linux/ath79/patches-5.15/408-mtd-redboot_partition_scan.patch
@@ -19,7 +19,7 @@
  				return -EIO;
  			}
  			offset -= master->erasesize;
-@@ -108,10 +113,6 @@ nogood:
+@@ -108,10 +114,6 @@ nogood:
  				goto nogood;
  		}
  	}
@@ -30,7 +30,7 @@
  
  	pr_notice("Searching for RedBoot partition table in %s at offset 0x%lx\n",
  		  master->name, offset);
-@@ -183,6 +184,12 @@ nogood:
+@@ -183,6 +185,12 @@ nogood:
  	}
  	if (i == numslots) {
  		/* Didn't find it */
diff --git a/target/linux/ath79/patches-5.15/600-of_net-add-mac-address-ascii-support.patch b/target/linux/ath79/patches-5.15/600-of_net-add-mac-address-ascii-support.patch
new file mode 100644
index 0000000000..8849afb4d6
--- /dev/null
+++ b/target/linux/ath79/patches-5.15/600-of_net-add-mac-address-ascii-support.patch
@@ -0,0 +1,103 @@
+Index: linux-5.15.31/net/ethernet/eth.c
+===================================================================
+--- linux-5.15.31.orig/net/ethernet/eth.c
++++ linux-5.15.31/net/ethernet/eth.c
+@@ -544,6 +544,63 @@ int eth_platform_get_mac_address(struct
+ }
+ EXPORT_SYMBOL(eth_platform_get_mac_address);
+ 
++static void *nvmem_cell_get_mac_address(struct nvmem_cell *cell)
++{
++	size_t len;
++	void *mac;
++
++	mac = nvmem_cell_read(cell, &len);
++	if (IS_ERR(mac))
++		return PTR_ERR(mac);
++	if (len != ETH_ALEN) {
++		kfree(mac);
++		return ERR_PTR(-EINVAL);
++	}
++	return mac;
++}
++
++static void *nvmem_cell_get_mac_address_ascii(struct nvmem_cell *cell)
++{
++	size_t len;
++	int ret;
++	void *mac_ascii;
++	u8 *mac;
++
++	mac_ascii = nvmem_cell_read(cell, &len);
++	if (IS_ERR(mac_ascii))
++		return PTR_ERR(mac_ascii);
++	if (len != ETH_ALEN*2+5) {
++		kfree(mac_ascii);
++		return ERR_PTR(-EINVAL);
++	}
++	mac = kmalloc(ETH_ALEN, GFP_KERNEL);
++	if (!mac) {
++		kfree(mac_ascii);
++		return ERR_PTR(-ENOMEM);
++	}
++	ret = sscanf(mac_ascii, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
++				&mac[0], &mac[1], &mac[2],
++				&mac[3], &mac[4], &mac[5]);
++	kfree(mac_ascii);
++	if (ret == ETH_ALEN)
++		return mac;
++	kfree(mac);
++	return ERR_PTR(-EINVAL);
++}
++
++static struct nvmem_cell_mac_address_property {
++	char *name;
++	void *(*read)(struct nvmem_cell *);
++} nvmem_cell_mac_address_properties[] = {
++	{
++		.name = "mac-address",
++		.read = nvmem_cell_get_mac_address,
++	}, {
++		.name = "mac-address-ascii",
++		.read = nvmem_cell_get_mac_address_ascii,
++	},
++};
++
+ /**
+  * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
+  * 'mac-address' associated with given device.
+@@ -557,19 +614,23 @@ int nvmem_get_mac_address(struct device
+ {
+ 	struct nvmem_cell *cell;
+ 	const void *mac;
+-	size_t len;
++	struct nvmem_cell_mac_address_property *property;
++	int i;
+ 
+-	cell = nvmem_cell_get(dev, "mac-address");
+-	if (IS_ERR(cell))
+-		return PTR_ERR(cell);
+-
+-	mac = nvmem_cell_read(cell, &len);
+-	nvmem_cell_put(cell);
+-
+-	if (IS_ERR(mac))
+-		return PTR_ERR(mac);
++	for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
++		property = &nvmem_cell_mac_address_properties[i];
++		cell = nvmem_cell_get(dev, property->name);
++		if (IS_ERR(cell)) {
++			if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1)
++				return PTR_ERR(cell);
++			continue;
++		}
++		mac = property->read(cell);
++		nvmem_cell_put(cell);
++		break;
++	}
+ 
+-	if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
++	if (!is_valid_ether_addr(mac)) {
+ 		kfree(mac);
+ 		return -EINVAL;
+ 	}
diff --git a/target/linux/generic/backport-5.10/770-v5.15-net-dsa-mt7530-support-MDB-operations.patch b/target/linux/generic/backport-5.10/770-v5.15-net-dsa-mt7530-support-MDB-operations.patch
index 5d91d5a657..7143748eee 100644
--- a/target/linux/generic/backport-5.10/770-v5.15-net-dsa-mt7530-support-MDB-operations.patch
+++ b/target/linux/generic/backport-5.10/770-v5.15-net-dsa-mt7530-support-MDB-operations.patch
@@ -14,7 +14,7 @@ Signed-off-by: DENG Qingfang <dqfext@gmail.com>
 
 --- a/drivers/net/dsa/mt7530.c
 +++ b/drivers/net/dsa/mt7530.c
-@@ -1000,9 +1000,6 @@ mt753x_cpu_port_enable(struct dsa_switch
+@@ -998,9 +998,6 @@ mt753x_cpu_port_enable(struct dsa_switch
  	mt7530_write(priv, MT7530_PVC_P(port),
  		     PORT_SPEC_TAG);
  
@@ -24,7 +24,7 @@ Signed-off-by: DENG Qingfang <dqfext@gmail.com>
  	/* Set CPU port number */
  	if (priv->id == ID_MT7621)
  		mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
-@@ -1138,6 +1135,20 @@ mt7530_stp_state_set(struct dsa_switch *
+@@ -1131,6 +1128,20 @@ mt7530_stp_state_set(struct dsa_switch *
  }
  
  static int
@@ -45,7 +45,7 @@ Signed-off-by: DENG Qingfang <dqfext@gmail.com>
  mt7530_port_bridge_join(struct dsa_switch *ds, int port,
  			struct net_device *bridge)
  {
-@@ -1357,6 +1368,63 @@ err:
+@@ -1331,6 +1342,63 @@ err:
  }
  
  static int
@@ -109,7 +109,7 @@ Signed-off-by: DENG Qingfang <dqfext@gmail.com>
  mt7530_vlan_cmd(struct mt7530_priv *priv, enum mt7530_vlan_cmd cmd, u16 vid)
  {
  	struct mt7530_dummy_poll p;
-@@ -2794,11 +2862,15 @@ static const struct dsa_switch_ops mt753
+@@ -2745,11 +2813,15 @@ static const struct dsa_switch_ops mt753
  	.port_change_mtu	= mt7530_port_change_mtu,
  	.port_max_mtu		= mt7530_port_max_mtu,
  	.port_stp_state_set	= mt7530_stp_state_set,
diff --git a/target/linux/generic/backport-5.10/772-v5.14-net-dsa-mt7530-add-interrupt-support.patch b/target/linux/generic/backport-5.10/772-v5.14-net-dsa-mt7530-add-interrupt-support.patch
index 9890015301..1ee2e1cac4 100644
--- a/target/linux/generic/backport-5.10/772-v5.14-net-dsa-mt7530-add-interrupt-support.patch
+++ b/target/linux/generic/backport-5.10/772-v5.14-net-dsa-mt7530-add-interrupt-support.patch
@@ -27,7 +27,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  #include <linux/of_mdio.h>
  #include <linux/of_net.h>
  #include <linux/of_platform.h>
-@@ -602,18 +603,14 @@ mt7530_mib_reset(struct dsa_switch *ds)
+@@ -600,18 +601,14 @@ mt7530_mib_reset(struct dsa_switch *ds)
  	mt7530_write(priv, MT7530_MIB_CCR, CCR_MIB_ACTIVATE);
  }
  
@@ -48,7 +48,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  	return mdiobus_write_nested(priv->bus, port, regnum, val);
  }
  
-@@ -791,9 +788,8 @@ out:
+@@ -789,9 +786,8 @@ out:
  }
  
  static int
@@ -59,7 +59,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  	int devad;
  	int ret;
  
-@@ -809,10 +805,9 @@ mt7531_ind_phy_read(struct dsa_switch *d
+@@ -807,10 +803,9 @@ mt7531_ind_phy_read(struct dsa_switch *d
  }
  
  static int
@@ -71,7 +71,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  	int devad;
  	int ret;
  
-@@ -828,6 +823,22 @@ mt7531_ind_phy_write(struct dsa_switch *
+@@ -826,6 +821,22 @@ mt7531_ind_phy_write(struct dsa_switch *
  	return ret;
  }
  
@@ -94,7 +94,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  static void
  mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,
  		   uint8_t *data)
-@@ -1824,6 +1835,210 @@ mt7530_setup_gpio(struct mt7530_priv *pr
+@@ -1793,6 +1804,210 @@ mt7530_setup_gpio(struct mt7530_priv *pr
  	return devm_gpiochip_add_data(dev, gc, priv);
  }
  
@@ -305,7 +305,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  static int
  mt7530_setup(struct dsa_switch *ds)
  {
-@@ -2798,24 +3013,20 @@ static int
+@@ -2749,24 +2964,20 @@ static int
  mt753x_setup(struct dsa_switch *ds)
  {
  	struct mt7530_priv *priv = ds->priv;
@@ -340,7 +340,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  }
  
  static int mt753x_get_mac_eee(struct dsa_switch *ds, int port,
-@@ -2852,8 +3063,6 @@ static const struct dsa_switch_ops mt753
+@@ -2803,8 +3014,6 @@ static const struct dsa_switch_ops mt753
  	.get_tag_protocol	= mtk_get_tag_protocol,
  	.setup			= mt753x_setup,
  	.get_strings		= mt7530_get_strings,
@@ -349,7 +349,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  	.get_ethtool_stats	= mt7530_get_ethtool_stats,
  	.get_sset_count		= mt7530_get_sset_count,
  	.set_ageing_time	= mt7530_set_ageing_time,
-@@ -3036,6 +3245,9 @@ mt7530_remove(struct mdio_device *mdiode
+@@ -2987,6 +3196,9 @@ mt7530_remove(struct mdio_device *mdiode
  		dev_err(priv->dev, "Failed to disable io pwr: %d\n",
  			ret);
  
@@ -369,7 +369,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  #define MT7530_CPU_PORT			6
  #define MT7530_NUM_FDB_RECORDS		2048
  #define MT7530_ALL_MEMBERS		0xff
-@@ -401,6 +402,12 @@ enum mt7531_sgmii_force_duplex {
+@@ -392,6 +393,12 @@ enum mt7531_sgmii_force_duplex {
  #define  SYS_CTRL_SW_RST		BIT(1)
  #define  SYS_CTRL_REG_RST		BIT(0)
  
@@ -382,7 +382,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  /* Register for PHY Indirect Access Control */
  #define MT7531_PHY_IAC			0x701C
  #define  MT7531_PHY_ACS_ST		BIT(31)
-@@ -722,6 +729,8 @@ static const char *p5_intf_modes(unsigne
+@@ -713,6 +720,8 @@ static const char *p5_intf_modes(unsigne
  	}
  }
  
@@ -391,7 +391,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  /* struct mt753x_info -	This is the main data structure for holding the specific
   *			part for each supported device
   * @sw_setup:		Holding the handler to a device initialization
-@@ -746,8 +755,8 @@ struct mt753x_info {
+@@ -737,8 +746,8 @@ struct mt753x_info {
  	enum mt753x_id id;
  
  	int (*sw_setup)(struct dsa_switch *ds);
@@ -402,7 +402,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  	int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
  	int (*cpu_port_config)(struct dsa_switch *ds, int port);
  	bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
-@@ -781,6 +790,10 @@ struct mt753x_info {
+@@ -772,6 +781,10 @@ struct mt753x_info {
   *			registers
   * @p6_interface	Holding the current port 6 interface
   * @p5_intf_sel:	Holding the current port 5 interface select
@@ -413,7 +413,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
   */
  struct mt7530_priv {
  	struct device		*dev;
-@@ -802,6 +815,9 @@ struct mt7530_priv {
+@@ -793,6 +806,9 @@ struct mt7530_priv {
  	struct mt7530_port	ports[MT7530_NUM_PORTS];
  	/* protect among processes for registers access*/
  	struct mutex reg_mutex;
