Merge "[rdkb][common][app][Fix wifi reload failed when ap is down]"
diff --git a/conf/machine/filogic.conf b/conf/machine/filogic.conf
index 38f8ba2..938c260 100644
--- a/conf/machine/filogic.conf
+++ b/conf/machine/filogic.conf
@@ -13,11 +13,18 @@
MACHINEOVERRIDES .="${@bb.utils.contains('DISTRO_FEATURES','switch_gsw_mode',':gsw','',d)}"
-KERNEL_DEVICETREE_gsw = " \
+KERNEL_DEVICETREE_mt7988_gsw = " \
+ mediatek/mt7988a-gsw-10g-spim-nand.dtb \
+ "
+
+KERNEL_DEVICETREE_mt7988 = " \
+ mediatek/mt7988a-dsa-10g-spim-nand.dtb \
+ "
+KERNEL_DEVICETREE_mt7986_gsw = " \
mediatek/mt7986a-2500wan-gsw-spim-nand-rfb.dtb \
mediatek/mt7986b-2500wan-gsw-spim-nand-rfb.dtb \
"
-KERNEL_DEVICETREE ?= " \
+KERNEL_DEVICETREE_mt7986 = " \
mediatek/mt7986a-spim-nand-rfb.dtb \
mediatek/mt7986b-spim-nand-rfb.dtb \
"
diff --git a/recipes-devtools/wifi-test-tool/files/src/wifi-test-tool.c b/recipes-devtools/wifi-test-tool/files/src/wifi-test-tool.c
index 024733c..0682965 100644
--- a/recipes-devtools/wifi-test-tool/files/src/wifi-test-tool.c
+++ b/recipes-devtools/wifi-test-tool/files/src/wifi-test-tool.c
@@ -5,6 +5,60 @@
#include <uci.h>
#include "wifi-test-tool.h"
+
+static int _syscmd(char *cmd, char *retBuf, int retBufSize)
+{
+ FILE *f;
+ char *ptr = retBuf;
+ int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
+
+
+ if((f = popen(cmd, "r")) == NULL) {
+ fprintf(stderr,"\npopen %s error\n", cmd);
+ return RETURN_ERR;
+ }
+
+ while(!feof(f))
+ {
+ *ptr = 0;
+ if(bufSize>=128) {
+ bufbytes=128;
+ } else {
+ bufbytes=bufSize-1;
+ }
+
+ fgets(ptr,bufbytes,f);
+ readbytes=strlen(ptr);
+
+ if(!readbytes)
+ break;
+
+ bufSize-=readbytes;
+ ptr += readbytes;
+ }
+ cmd_ret = pclose(f);
+ retBuf[retBufSize-1]=0;
+
+ return cmd_ret >> 8;
+}
+
+int phy_index_to_radio(int phyIndex)
+{
+ char cmd[128] = {0};
+ char buf[64] = {0};
+ int radioIndex = 0;
+ snprintf(cmd, sizeof(cmd), "ls /tmp | grep phy%d | cut -d '-' -f2 | tr -d '\n'", phyIndex);
+ _syscmd(cmd, buf, sizeof(buf));
+
+ if (strlen(buf) == 0 || strstr(buf, "wifi") == NULL) {
+ fprintf(stderr, "%s: failed to get wifi index\n", __func__);
+ return RETURN_ERR;
+ }
+ sscanf(buf, "wifi%d", &radioIndex);
+ fprintf(stderr, "%s: radio index = %d \n", __func__, radioIndex);
+ return radioIndex;
+}
+
void set_channel(wifi_radio_param *radio_param, char *channel)
{
if (strcmp(channel, "auto") == 0) {
@@ -27,6 +81,12 @@
strcpy(radio_param->band, band);
}
+void set_noscan(wifi_radio_param *radio_param, char *noscan)
+{
+ snprintf(radio_param->noscan, 2, "%s", noscan);
+ radio_param->noscan[1] = '\0';
+}
+
void set_hwmode(wifi_radio_param *radio_param, char *hwmode)
{
if (strncmp(hwmode, "11a", 3) == 0)
@@ -89,11 +149,13 @@
{
int radio_num;
char *ptr = radio_name;
+ int phyId = 0;
while (*ptr) {
if (isdigit(*ptr)) {
radio_num = strtoul(ptr, NULL, 10);
- ap_param->radio_index = radio_num;
+ phyId = phy_index_to_radio(radio_num);
+ ap_param->radio_index = phyId;
break;
}
ptr++;
@@ -186,6 +248,9 @@
struct params param;
wifi_radio_operationParam_t operationParam = {0};
+ if(radio_parameter.radio_index == -1)
+ return;
+
if (radio_parameter.disabled == TRUE) {
wifi_setRadioEnable(radio_parameter.radio_index, FALSE);
return;
@@ -247,7 +312,9 @@
if (strstr(radio_parameter.htmode, "HE") != NULL)
mode |= WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX;
- }
+ }else if (strcmp(radio_parameter.band, "6g") == 0) {
+ mode |= WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX;;
+ }
if (strstr(radio_parameter.htmode, "VHT") != NULL)
mode |= WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC;
@@ -256,6 +323,13 @@
operationParam.variant = mode;
+ // noscan
+ fprintf(stderr, "Set noscan: %s\n", radio_parameter.noscan);
+ ret = wifi_setNoscan(radio_parameter.radio_index, radio_parameter.noscan);
+ if (ret != RETURN_OK)
+ fprintf(stderr, "[Set noscan failed!!!]\n");
+ ret = 0;
+
// apply setting
ret = wifi_setRadioOperatingParameters(radio_parameter.radio_index, &operationParam);
if (ret != RETURN_OK)
@@ -275,7 +349,8 @@
if (radio_enable == FALSE)
return;
- // get current setting
+ if(ap_param.radio_index == -1)
+ return;
ret = wifi_getRadioVapInfoMap(ap_param.radio_index, &vap_map);
if (ret != RETURN_OK) { // if failed, we set assume this vap as the first vap.
fprintf(stderr, "[Get vap map failed!!!]\n");
@@ -307,6 +382,8 @@
vap_info.u.bss_info.security.mfp = ap_param.security.mfp;
vap_info.u.bss_info.security.u.key.type = ap_param.security.u.key.type;
strncpy(vap_info.u.bss_info.security.u.key.key, ap_param.security.u.key.key, 64);
+
+
// Replace the setting with uci config
vap_map.vap_array[vap_index_in_map] = vap_info;
ret = wifi_createVAP(ap_param.radio_index, &vap_map);
@@ -327,6 +404,7 @@
const char cfg_name[] = "wireless";
int max_radio_num = 0;
BOOL parsing_radio = FALSE;
+ int apCount[3] = {0};
wifi_getMaxRadioNumber(&max_radio_num);
fprintf(stderr, "max radio number: %d\n", max_radio_num);
@@ -342,17 +420,17 @@
struct uci_element *option = NULL;
wifi_radio_param radio_param = {0};
wifi_ap_param ap_param = {0};
+ int phyId = 0;
radio_param.radio_index = -1;
ap_param.ap_index = -1;
if (strcmp(s->type, "wifi-device") == 0) {
- sscanf(s->e.name, "radio%d", &radio_param.radio_index);
+ sscanf(s->e.name, "radio%d", &phyId);
+ radio_param.radio_index = phy_index_to_radio(phyId);
parsing_radio = TRUE;
fprintf(stderr, "\n----- Start parsing radio %d config. -----\n", radio_param.radio_index);
} else if (strcmp(s->type, "wifi-iface") == 0) {
- sscanf(s->e.name, "default_radio%d", &ap_param.ap_index);
parsing_radio = FALSE;
- fprintf(stderr, "\n----- Start parsing ap %d config. -----\n", ap_param.ap_index);
}
uci_foreach_element(&s->options, option) {
@@ -373,21 +451,27 @@
else if (strcmp(op->e.name, "country") == 0)
set_country(&radio_param, op->v.string);
else if (strcmp(op->e.name, "noscan") == 0)
- set_band(&radio_param, op->v.string);
+ set_noscan(&radio_param, op->v.string);
else
fprintf(stderr, "[%s %s not set!]\n", op->e.name, op->v.string);
} else {
// parsing iface
- if (strcmp(op->e.name, "device") == 0)
+ if (strcmp(op->e.name, "device") == 0){
set_radionum(&ap_param, op->v.string);
- else if (strcmp(op->e.name, "ssid") == 0)
+ if (ap_param.radio_index != -1){
+ ap_param.ap_index = ap_param.radio_index + apCount[ap_param.radio_index]*max_radio_num;
+ fprintf(stderr, "\n----- Start parsing ap %d config. -----\n", ap_param.ap_index);
+ apCount[ap_param.radio_index] ++ ;
+ }
+ }else if (strcmp(op->e.name, "ssid") == 0){
set_ssid(&ap_param, op->v.string);
- else if (strcmp(op->e.name, "encryption") == 0)
+ }else if (strcmp(op->e.name, "encryption") == 0){
set_encryption(&ap_param, op->v.string);
- else if (strcmp(op->e.name, "key") == 0)
+ }else if (strcmp(op->e.name, "key") == 0){
set_key(&ap_param, op->v.string);
- else
+ }else{
fprintf(stderr, "[%s %s not set!]\n", op->e.name, op->v.string);
+ }
}
}
if (parsing_radio == TRUE)
diff --git a/recipes-devtools/wifi-test-tool/files/src/wifi-test-tool.h b/recipes-devtools/wifi-test-tool/files/src/wifi-test-tool.h
index fb6b5b1..19af44a 100644
--- a/recipes-devtools/wifi-test-tool/files/src/wifi-test-tool.h
+++ b/recipes-devtools/wifi-test-tool/files/src/wifi-test-tool.h
@@ -41,6 +41,7 @@
char supported_rates[64];
int log_level;
char hostapd_options[64];
+ char noscan[2];
} wifi_radio_param;
typedef struct {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
index 09e8267..680ea7e 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
@@ -71,7 +71,7 @@
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
-@@ -6886,7 +6886,7 @@ static void __ref alloc_node_mem_map(str
+@@ -6931,7 +6931,7 @@ static void __ref alloc_node_mem_map(str
mem_map = NODE_DATA(0)->node_mem_map;
#if defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) || defined(CONFIG_FLATMEM)
if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/834-ledtrig-libata.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/834-ledtrig-libata.patch
index 1c6eb8c..4bb74ed 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/834-ledtrig-libata.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/834-ledtrig-libata.patch
@@ -65,7 +65,7 @@
/**
* ata_build_rw_tf - Build ATA taskfile for given read/write request
* @tf: Target ATA taskfile
-@@ -5155,6 +5168,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
+@@ -5159,6 +5172,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
if (tag < 0)
return NULL;
}
@@ -75,7 +75,7 @@
qc = __ata_qc_from_tag(ap, tag);
qc->tag = qc->hw_tag = tag;
-@@ -6091,6 +6107,9 @@ struct ata_port *ata_port_alloc(struct a
+@@ -6095,6 +6111,9 @@ struct ata_port *ata_port_alloc(struct a
ap->stats.unhandled_irq = 1;
ap->stats.idle_irq = 1;
#endif
@@ -85,7 +85,7 @@
ata_sff_port_init(ap);
return ap;
-@@ -6126,6 +6145,12 @@ static void ata_host_release(struct kref
+@@ -6130,6 +6149,12 @@ static void ata_host_release(struct kref
kfree(ap->pmp_link);
kfree(ap->slave_link);
@@ -98,7 +98,7 @@
kfree(ap);
host->ports[i] = NULL;
}
-@@ -6589,7 +6614,23 @@ int ata_host_register(struct ata_host *h
+@@ -6593,7 +6618,23 @@ int ata_host_register(struct ata_host *h
host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
host->ports[i]->local_port_no = i + 1;
}
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 16b872e..a4d3f2f 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
@@ -358,19 +358,23 @@
<&topckgen CK_TOP_NPU_TOPS_SEL>,
<&topckgen CK_TOP_CK_NPU_SEL_CM_TOPS_SEL>;
clock-names = "bus", "sram", "xdma", "offload", "mgmt";
+ power-domains = <&topmisc MT7988_POWER_DOMAIN_TOPS0>,
+ <&topmisc MT7988_POWER_DOMAIN_TOPS1>;
+
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "tdma-tx-pause", "mbox";
- topmisc = <&topmisc>;
+
fe_mem = <ð>;
- topckgen = <&topckgen>;
};
+
hpdma1: hpdma@09106000 {
compatible = "mediatek,hpdma-top";
reg = <0 0x09106000 0 0x1000>;
reg-names = "base";
};
+
hpdma2: hpdma@09606000 {
compatible = "mediatek,hpdma-sub";
reg = <0 0x09606000 0 0x1000>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
index c6f76bf..5ad8645 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
@@ -656,6 +656,26 @@
pr_info("+-----------------------------------------------+\n");
}
+void dump_each_port(struct seq_file *seq, struct mtk_eth *eth, u32 base)
+{
+ u32 pkt_cnt = 0;
+ int i = 0;
+
+ for (i = 0; i < 7; i++) {
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+ if ((base == 0x402C) && (i == 6))
+ base = 0x408C;
+ else if ((base == 0x408C) && (i == 6))
+ base = 0x402C;
+ else
+ ;
+ }
+ pkt_cnt = mt7530_mdio_r32(eth, (base) + (i * 0x100));
+ seq_printf(seq, "%8u ", pkt_cnt);
+ }
+ seq_puts(seq, "\n");
+}
+
int esw_cnt_read(struct seq_file *seq, void *v)
{
unsigned int pkt_cnt = 0;
@@ -669,56 +689,47 @@
mt798x_iomap();
-#define DUMP_EACH_PORT(base) \
- do { \
- for (i = 0; i < 7; i++) { \
- pkt_cnt = mt7530_mdio_r32(eth, (base) + (i * 0x100));\
- seq_printf(seq, "%8u ", pkt_cnt); \
- } \
- seq_puts(seq, "\n"); \
- } while (0)
-
seq_printf(seq, "===================== %8s %8s %8s %8s %8s %8s %8s\n",
"Port0", "Port1", "Port2", "Port3", "Port4", "Port5",
"Port6");
seq_puts(seq, "Tx Drop Packet :");
- DUMP_EACH_PORT(0x4000);
+ dump_each_port(seq, eth, 0x4000);
seq_puts(seq, "Tx CRC Error :");
- DUMP_EACH_PORT(0x4004);
+ dump_each_port(seq, eth, 0x4004);
seq_puts(seq, "Tx Unicast Packet :");
- DUMP_EACH_PORT(0x4008);
+ dump_each_port(seq, eth, 0x4008);
seq_puts(seq, "Tx Multicast Packet :");
- DUMP_EACH_PORT(0x400C);
+ dump_each_port(seq, eth, 0x400C);
seq_puts(seq, "Tx Broadcast Packet :");
- DUMP_EACH_PORT(0x4010);
+ dump_each_port(seq, eth, 0x4010);
seq_puts(seq, "Tx Collision Event :");
- DUMP_EACH_PORT(0x4014);
+ dump_each_port(seq, eth, 0x4014);
seq_puts(seq, "Tx Pause Packet :");
- DUMP_EACH_PORT(0x402C);
+ dump_each_port(seq, eth, 0x402C);
seq_puts(seq, "Rx Drop Packet :");
- DUMP_EACH_PORT(0x4060);
+ dump_each_port(seq, eth, 0x4060);
seq_puts(seq, "Rx Filtering Packet :");
- DUMP_EACH_PORT(0x4064);
+ dump_each_port(seq, eth, 0x4064);
seq_puts(seq, "Rx Unicast Packet :");
- DUMP_EACH_PORT(0x4068);
+ dump_each_port(seq, eth, 0x4068);
seq_puts(seq, "Rx Multicast Packet :");
- DUMP_EACH_PORT(0x406C);
+ dump_each_port(seq, eth, 0x406C);
seq_puts(seq, "Rx Broadcast Packet :");
- DUMP_EACH_PORT(0x4070);
+ dump_each_port(seq, eth, 0x4070);
seq_puts(seq, "Rx Alignment Error :");
- DUMP_EACH_PORT(0x4074);
+ dump_each_port(seq, eth, 0x4074);
seq_puts(seq, "Rx CRC Error :");
- DUMP_EACH_PORT(0x4078);
+ dump_each_port(seq, eth, 0x4078);
seq_puts(seq, "Rx Undersize Error :");
- DUMP_EACH_PORT(0x407C);
+ dump_each_port(seq, eth, 0x407C);
seq_puts(seq, "Rx Fragment Error :");
- DUMP_EACH_PORT(0x4080);
+ dump_each_port(seq, eth, 0x4080);
seq_puts(seq, "Rx Oversize Error :");
- DUMP_EACH_PORT(0x4084);
+ dump_each_port(seq, eth, 0x4084);
seq_puts(seq, "Rx Jabber Error :");
- DUMP_EACH_PORT(0x4088);
+ dump_each_port(seq, eth, 0x4088);
seq_puts(seq, "Rx Pause Packet :");
- DUMP_EACH_PORT(0x408C);
+ dump_each_port(seq, eth, 0x408C);
mt7530_mdio_w32(eth, 0x4fe0, 0xf0);
mt7530_mdio_w32(eth, 0x4fe0, 0x800000f0);
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 0eefd36..50729d6 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
@@ -538,7 +538,7 @@
switch(phydev->drv->phy_id) {
case 0x03a29481:
{
- int tmp[16] = { 1, 1, 1, 1 };
+ int tmp[16] = { -1, -1, -1, -1 };
memcpy(bias, (const void *)tmp, sizeof(bias));
break;
}
@@ -894,6 +894,13 @@
/* Disable TX power saving */
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);
+ __phy_write(phydev, 0x12, 0x0);
+ __phy_write(phydev, 0x11, 0x750);
+ __phy_write(phydev, 0x10, 0x9686);
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
}
static int mt798x_phy_calibration(struct phy_device *phydev)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
new file mode 100644
index 0000000..75db83e
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
@@ -0,0 +1,488 @@
+CONFIG_64BIT=y
+CONFIG_AHCI_MTK=y
+# CONFIG_AIROHA_EN8801SC_PHY is not set
+# CONFIG_AIROHA_EN8801S_PHY is not set
+CONFIG_AQUANTIA_PHY=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=24
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM64=y
+CONFIG_ARM64_4K_PAGES=y
+CONFIG_ARM64_CNP=y
+CONFIG_ARM64_CONT_SHIFT=4
+CONFIG_ARM64_ERRATUM_1165522=y
+CONFIG_ARM64_ERRATUM_1286807=y
+CONFIG_ARM64_ERRATUM_1418040=y
+CONFIG_ARM64_HW_AFDBM=y
+CONFIG_ARM64_PAGE_SHIFT=12
+CONFIG_ARM64_PAN=y
+CONFIG_ARM64_PA_BITS=48
+CONFIG_ARM64_PA_BITS_48=y
+CONFIG_ARM64_PTR_AUTH=y
+CONFIG_ARM64_SSBD=y
+CONFIG_ARM64_SVE=y
+# CONFIG_ARM64_SW_TTBR0_PAN is not set
+CONFIG_ARM64_TAGGED_ADDR_ABI=y
+CONFIG_ARM64_UAO=y
+CONFIG_ARM64_VA_BITS=39
+CONFIG_ARM64_VA_BITS_39=y
+CONFIG_ARM64_VHE=y
+CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
+# CONFIG_ARMV8_DEPRECATED is not set
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GIC_V2M=y
+CONFIG_ARM_GIC_V3=y
+CONFIG_ARM_GIC_V3_ITS=y
+CONFIG_ARM_GIC_V3_ITS_PCI=y
+CONFIG_ARM_MEDIATEK_CPUFREQ=y
+CONFIG_ARM_PMU=y
+CONFIG_ARM_PSCI_FW=y
+CONFIG_ATA=y
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_BLK_DEV_DM_BUILTIN=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BLK_SCSI_REQUEST=y
+CONFIG_BLOCK_COMPAT=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_BT=y
+CONFIG_BT_BCM=y
+CONFIG_BT_BREDR=y
+CONFIG_BT_DEBUGFS=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_BCM=y
+# CONFIG_BT_HCIUART_INTEL is not set
+# CONFIG_BT_HCIUART_NOKIA is not set
+CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_HCIUART_SERDEV=y
+CONFIG_BT_HCIVHCI=y
+CONFIG_BT_HS=y
+CONFIG_BT_LE=y
+CONFIG_BT_MTKUART=y
+CONFIG_BT_QCA=y
+CONFIG_CAVIUM_TX2_ERRATUM_219=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_MEDIATEK=y
+CONFIG_COMMON_CLK_MT2712=y
+# CONFIG_COMMON_CLK_MT2712_BDPSYS is not set
+# CONFIG_COMMON_CLK_MT2712_IMGSYS is not set
+# CONFIG_COMMON_CLK_MT2712_JPGDECSYS is not set
+# CONFIG_COMMON_CLK_MT2712_MFGCFG is not set
+# CONFIG_COMMON_CLK_MT2712_MMSYS is not set
+# CONFIG_COMMON_CLK_MT2712_VDECSYS is not set
+# CONFIG_COMMON_CLK_MT2712_VENCSYS is not set
+# CONFIG_COMMON_CLK_MT6779 is not set
+# CONFIG_COMMON_CLK_MT6797 is not set
+CONFIG_COMMON_CLK_MT7622=y
+CONFIG_COMMON_CLK_MT7622_AUDSYS=y
+CONFIG_COMMON_CLK_MT7622_ETHSYS=y
+CONFIG_COMMON_CLK_MT7622_HIFSYS=y
+CONFIG_COMMON_CLK_MT7981=y
+CONFIG_COMMON_CLK_MT7986=y
+CONFIG_COMMON_CLK_MT7988=y
+# CONFIG_COMMON_CLK_MT8173 is not set
+# CONFIG_COMMON_CLK_MT8183 is not set
+# CONFIG_COMMON_CLK_MT8516 is not set
+CONFIG_COMPAT=y
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_COMPAT_BINFMT_ELF=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
+CONFIG_COMPAT_OLD_SIGACTION=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
+# CONFIG_CPUFREQ_DT is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_ACOMP2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ECC=y
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_KPP=y
+CONFIG_CRYPTO_KPP2=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_NULL2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_MISC=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMADEVICES=y
+CONFIG_DMATEST=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_ENGINE_RAID=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_REMAP=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DM_BUFIO=y
+# CONFIG_DM_CRYPT is not set
+# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set
+# CONFIG_DM_INIT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_SNAPSHOT is not set
+CONFIG_DM_VERITY=y
+# CONFIG_DM_VERITY_FEC is not set
+# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set
+CONFIG_DRM_RCAR_WRITEBACK=y
+CONFIG_DTC=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EINT_MTK=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FUJITSU_ERRATUM_010001=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPY211_PHY=y
+CONFIG_GRO_CELLS=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HOLES_IN_ZONE=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HWMON=y
+# CONFIG_HW_NAT is not set
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MTK=y
+CONFIG_HZ=250
+CONFIG_HZ_250=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_MT65XX=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_IIO=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IO_URING=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JUMP_LABEL=y
+# CONFIG_LEDS_UBNT_LEDBAR is not set
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAGIC_SYSRQ_SERIAL=y
+CONFIG_MAXLINEAR_GPHY=y
+CONFIG_MD=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_I2C=y
+CONFIG_MEDIATEK_2P5GE_PHY=y
+CONFIG_MEDIATEK_GE_PHY=y
+CONFIG_MEDIATEK_MT6577_AUXADC=y
+# CONFIG_MEDIATEK_NETSYS_V2 is not set
+CONFIG_MEDIATEK_NETSYS_V3=y
+CONFIG_MEDIATEK_WATCHDOG=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_MTK=y
+CONFIG_MODULES_TREE_LOOKUP=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MT753X_GSW=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+CONFIG_MTD_NAND_MTK=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_SPI_NAND=y
+# CONFIG_MTD_SPI_NAND_W25N01KV is not set
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_FIT_FW=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+# CONFIG_MTK_CMDQ is not set
+# CONFIG_MTK_CQDMA is not set
+CONFIG_MTK_EFUSE=y
+CONFIG_MTK_HSDMA=y
+CONFIG_MTK_ICE_DEBUG=y
+CONFIG_MTK_INFRACFG=y
+CONFIG_MTK_PMIC_WRAP=y
+CONFIG_MTK_SCPSYS=y
+CONFIG_MTK_SPI_NAND=y
+# CONFIG_MTK_THERMAL is not set
+CONFIG_MTK_SOC_THERMAL_LVTS=y
+CONFIG_MTK_TIMER=y
+# CONFIG_MTK_UART_APDMA is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MT7530=y
+CONFIG_NET_DSA_TAG_MTK=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_MEDIATEK_SOC=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_VENDOR_MEDIATEK=y
+CONFIG_NLS=y
+CONFIG_NMBM=y
+# CONFIG_NMBM_LOG_LEVEL_DEBUG is not set
+# CONFIG_NMBM_LOG_LEVEL_EMERG is not set
+# CONFIG_NMBM_LOG_LEVEL_ERR is not set
+CONFIG_NMBM_LOG_LEVEL_INFO=y
+# CONFIG_NMBM_LOG_LEVEL_NONE is not set
+# CONFIG_NMBM_LOG_LEVEL_WARN is not set
+CONFIG_NMBM_MTD=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=4
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PADATA=y
+CONFIG_PARTITION_PERCPU=y
+CONFIG_PCI=y
+# CONFIG_PCIE_MEDIATEK is not set
+CONFIG_PCIE_MEDIATEK_GEN3=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+# CONFIG_PHY_MTK_A60810 is not set
+# CONFIG_PHY_MTK_A60931 is not set
+# CONFIG_PHY_MTK_A60XXX is not set
+CONFIG_PHY_MTK_TPHY=y
+# CONFIG_PHY_MTK_UFS is not set
+# CONFIG_PHY_MTK_USB3_I2C_FPGA is not set
+CONFIG_PHY_MTK_XSPHY=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_MT2712 is not set
+# CONFIG_PINCTRL_MT6765 is not set
+# CONFIG_PINCTRL_MT6797 is not set
+# CONFIG_PINCTRL_MT7622 is not set
+# CONFIG_PINCTRL_MT7981 is not set
+CONFIG_PINCTRL_MT7986=y
+CONFIG_PINCTRL_MT7988=y
+# CONFIG_PINCTRL_MT8173 is not set
+# CONFIG_PINCTRL_MT8183 is not set
+CONFIG_PINCTRL_MT8516=y
+CONFIG_PINCTRL_MTK=y
+CONFIG_PINCTRL_MTK_MOORE=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_PM_OPP=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PWM=y
+CONFIG_PWM_MEDIATEK=y
+# CONFIG_PWM_MTK_DISP is not set
+CONFIG_PWM_SYSFS=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+# CONFIG_RAVE_SP_CORE is not set
+CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_MT6380=y
+CONFIG_REGULATOR_RT5190A=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MT7622=y
+CONFIG_RTC_I2C_AND_SPI=y
+# CONFIG_RTL8367S_GSW is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCHED_MC=y
+CONFIG_SCSI=y
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
+# CONFIG_SENSORS_DRIVETEMP is not set
+CONFIG_SENSORS_PWM_FAN=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_MT6577=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SFP=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_MT65XX=y
+# CONFIG_SPI_MTK_NOR is not set
+CONFIG_SPI_MTK_SNFI=y
+CONFIG_SRCU=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_EMULATION=y
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UCLAMP_TASK is not set
+# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_UAS=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MTK=y
+CONFIG_USB_XHCI_MTK_DEBUGFS=y
+# CONFIG_USB_XHCI_PLATFORM is not set
+CONFIG_VMAP_STACK=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
+# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_XPS=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0007-cpufreq-mtk-vbining-add-mt7988-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0007-cpufreq-mtk-vbining-add-mt7988-support.patch
index 8e99118..aa31f22 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0007-cpufreq-mtk-vbining-add-mt7988-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0007-cpufreq-mtk-vbining-add-mt7988-support.patch
@@ -15,10 +15,10 @@
struct cpufreq_frequency_table *freq_table;
int ret;
+ int target_vproc;
-+ u32 reg_val;
++ u8 reg_val;
+ struct nvmem_cell *cell;
+ size_t len;
-+ u32 *buf;
++ u8 *buf;
info = mtk_cpu_dvfs_info_lookup(policy->cpu);
if (!info) {
@@ -28,7 +28,7 @@
+ cell = nvmem_cell_get(info->cpu_dev, "calibration-data");
+ if (!IS_ERR(cell)) {
-+ buf = (u32 *)nvmem_cell_read(cell, &len);
++ buf = (u8 *)nvmem_cell_read(cell, &len);
+ nvmem_cell_put(cell);
+ if (!IS_ERR(buf)) {
+ reg_val = buf[0] & 0x1f;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/750-add-mdio-bus-for-gphy-calibration.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/750-add-mdio-bus-for-gphy-calibration.patch
new file mode 100755
index 0000000..e3efa34
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/750-add-mdio-bus-for-gphy-calibration.patch
@@ -0,0 +1,133 @@
+Index: linux-5.4.215/drivers/net/dsa/mt7530.c
+===================================================================
+--- linux-5.4.215.orig/drivers/net/dsa/mt7530.c
++++ linux-5.4.215/drivers/net/dsa/mt7530.c
+@@ -847,6 +847,117 @@ mt7531_ind_phy_write(struct dsa_switch *
+ return ret;
+ }
+
++static int mt753x_mdio_read(struct mii_bus *bus, int addr, int regnum)
++{
++ struct mt7530_priv *priv = bus->priv;
++ struct mt7530_dummy_poll p;
++ int ret;
++ u32 val;
++
++ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
++
++ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++
++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++ !(val & MT7531_PHY_ACS_ST), 20, 100000);
++ if (ret < 0) {
++ dev_err(priv->dev, "poll timeout\n");
++ goto out;
++ }
++
++ val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(addr) |
++ MT7531_MDIO_REG_ADDR(regnum);
++
++ mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
++
++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++ !(val & MT7531_PHY_ACS_ST), 20, 100000);
++ if (ret < 0) {
++ dev_err(priv->dev, "poll timeout\n");
++ goto out;
++ }
++
++ ret = val & MT7531_MDIO_RW_DATA_MASK;
++out:
++ mutex_unlock(&priv->bus->mdio_lock);
++
++ return ret;
++}
++
++static int mt753x_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
++{
++ struct mt7530_priv *priv = bus->priv;
++ struct mt7530_dummy_poll p;
++ int ret;
++ u32 reg;
++
++ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
++
++ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++
++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
++ !(reg & MT7531_PHY_ACS_ST), 20, 100000);
++ if (ret < 0) {
++ dev_err(priv->dev, "poll timeout\n");
++ goto out;
++ }
++
++ reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(addr) |
++ MT7531_MDIO_REG_ADDR(regnum) | val;
++
++ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
++
++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
++ !(reg & MT7531_PHY_ACS_ST), 20, 100000);
++ if (ret < 0) {
++ dev_err(priv->dev, "poll timeout\n");
++ goto out;
++ }
++
++out:
++ mutex_unlock(&priv->bus->mdio_lock);
++
++ return ret;
++}
++
++static int mt753x_setup_mdio(struct dsa_switch *ds)
++{
++ struct mt7530_priv *priv = ds->priv;
++ struct device_node *mdio_np;
++ int ret;
++
++ mdio_np = of_get_compatible_child(priv->dev->of_node, "mediatek,dsa-slave-mdio");
++ if (!mdio_np) {
++ dev_err(priv->dev, "no MDIO bus node\n");
++ return -ENODEV;
++ }
++
++ priv->ds->slave_mii_bus = devm_mdiobus_alloc(priv->dev);
++ if (!priv->ds->slave_mii_bus) {
++ ret = -ENOMEM;
++ goto err_put_node;
++ }
++ priv->ds->slave_mii_bus->name = "mediatek,dsa-slave-mdio";
++ priv->ds->slave_mii_bus->priv = priv;
++ priv->ds->slave_mii_bus->parent = priv->dev;
++ priv->ds->slave_mii_bus->phy_mask = ~priv->ds->phys_mii_mask;
++ priv->ds->slave_mii_bus->read = mt753x_mdio_read;
++ priv->ds->slave_mii_bus->write = mt753x_mdio_write;
++ snprintf(priv->ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d.%d",
++ priv->ds->dst->index, priv->ds->index);
++ priv->ds->slave_mii_bus->dev.of_node = mdio_np;
++
++ ret = of_mdiobus_register(priv->ds->slave_mii_bus, mdio_np);
++ if (ret)
++ dev_err(priv->dev, "unable to register MDIO bus %s\n",
++ priv->ds->slave_mii_bus->id);
++
++err_put_node:
++ of_node_put(mdio_np);
++
++ return ret;
++}
++
+ static void
+ mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,
+ uint8_t *data)
+@@ -2694,6 +2805,10 @@ mt7988_setup(struct dsa_switch *ds)
+ if (ret < 0)
+ return ret;
+
++ ret = mt753x_setup_mdio(ds);
++ if (ret < 0)
++ dev_err(priv->dev, "mt753x_setup_mdio failed\n");
++
+ return 0;
+ }
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/750-add-mdio-bus-for-phy-node.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/750-add-mdio-bus-for-phy-node.patch
deleted file mode 100644
index 5a130b1..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/750-add-mdio-bus-for-phy-node.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-Index: linux-5.4.203/drivers/net/dsa/mt7530.c
-===================================================================
---- linux-5.4.203.orig/drivers/net/dsa/mt7530.c
-+++ linux-5.4.203/drivers/net/dsa/mt7530.c
-@@ -847,6 +847,132 @@ mt7531_ind_phy_write(struct dsa_switch *
- return ret;
- }
-
-+static int mt753x_mdio_read(struct mii_bus *bus, int addr, int regnum)
-+{
-+ struct mt7530_priv *priv = bus->priv;
-+ struct mt7530_dummy_poll p;
-+ int ret;
-+ u32 val;
-+
-+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-+
-+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(addr) |
-+ MT7531_MDIO_REG_ADDR(regnum);
-+
-+ mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ ret = val & MT7531_MDIO_RW_DATA_MASK;
-+out:
-+ mutex_unlock(&priv->bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static int mt753x_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
-+{
-+ struct mt7530_priv *priv = bus->priv;
-+ struct mt7530_dummy_poll p;
-+ int ret;
-+ u32 reg;
-+
-+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-+
-+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
-+ !(reg & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(addr) |
-+ MT7531_MDIO_REG_ADDR(regnum) | val;
-+
-+ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
-+ !(reg & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+out:
-+ mutex_unlock(&priv->bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static int mt753x_mdio_init(struct mt7530_priv *priv)
-+{
-+ struct device_node *dn;
-+ struct device_node *mii_np;
-+ int ret;
-+
-+ dn = priv->dev->of_node;
-+
-+ mii_np = of_get_child_by_name(dn, "mdio-bus");
-+ if (!mii_np) {
-+ ret = -ENODEV;
-+ goto err_put_node;
-+ }
-+
-+ if (!of_device_is_available(mii_np)) {
-+ ret = -ENODEV;
-+ goto err_put_node;
-+ }
-+
-+ priv->gbus = devm_mdiobus_alloc(priv->dev);
-+ if (!priv->gbus) {
-+ ret = -ENOMEM;
-+ goto err_put_node;
-+ }
-+ priv->gbus->name = "mt753x_mdio";
-+ priv->gbus->read = mt753x_mdio_read;
-+ priv->gbus->write = mt753x_mdio_write;
-+ priv->gbus->priv = priv;
-+ priv->gbus->parent = priv->dev;
-+
-+ if(snprintf(priv->gbus->id, MII_BUS_ID_SIZE, "%s@%s", mii_np->name, dn->name) < 0) {
-+ ret = -ENOMEM;
-+ goto err_put_node;
-+ }
-+
-+ ret = of_mdiobus_register(priv->gbus, mii_np);
-+ if (ret)
-+ priv->gbus = NULL;
-+
-+err_put_node:
-+ of_node_put(mii_np);
-+
-+ return ret;
-+}
-+
-+static void mt753x_mdio_exit(struct mt7530_priv *priv)
-+{
-+ if (!priv->gbus)
-+ return;
-+
-+ mdiobus_unregister(priv->gbus);
-+}
-+
- static void
- mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,
- uint8_t *data)
-@@ -2892,6 +3018,7 @@ mt7530_probe(struct mdio_device *mdiodev
- return ret;
- }
- mt7530_nl_init(&priv);
-+ mt753x_mdio_init(priv);
-
- return 0;
- }
-@@ -2919,6 +3046,7 @@ mt7530_remove(struct mdio_device *mdiode
- iounmap(priv->base);
-
- mt7530_nl_exit();
-+ mt753x_mdio_exit(priv);
- }
-
- static struct mdio_driver mt7530_mdio_driver = {
-Index: linux-5.4.203/drivers/net/dsa/mt7530.h
-===================================================================
---- linux-5.4.203.orig/drivers/net/dsa/mt7530.h
-+++ linux-5.4.203/drivers/net/dsa/mt7530.h
-@@ -730,6 +730,7 @@ struct mt7530_priv {
- struct device *dev;
- struct dsa_switch *ds;
- struct mii_bus *bus;
-+ struct mii_bus *gbus;
- struct reset_control *rstc;
- struct regulator *core_pwr;
- struct regulator *io_pwr;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8011-ovs-add-multicast-to-unicast-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8011-ovs-add-multicast-to-unicast-support.patch
new file mode 100755
index 0000000..d0764d2
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8011-ovs-add-multicast-to-unicast-support.patch
@@ -0,0 +1,366 @@
+diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
+index 9e8a5c4..16f5187 100644
+--- a/net/openvswitch/actions.c
++++ b/net/openvswitch/actions.c
+@@ -919,6 +919,10 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
+ struct sw_flow_key *key)
+ {
+ struct vport *vport = ovs_vport_rcu(dp, out_port);
++ struct multicast_data_base *mdb;
++ struct multicast_table *table;
++ struct multicast_table_entry *entry;
++ struct sk_buff *skb_cpy;
+
+ if (likely(vport)) {
+ u16 mru = OVS_CB(skb)->mru;
+@@ -933,7 +937,28 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
+
+ if (likely(!mru ||
+ (skb->len <= mru + vport->dev->hard_header_len))) {
+- ovs_vport_send(vport, skb, ovs_key_mac_proto(key));
++ if (is_ipv4_multicast(skb) && !is_igmp(skb)) {
++ mdb = vport->mdb;
++ spin_lock(&mdb->tbl_lock);
++ list_for_each_entry(table, &mdb->list_head, mdb_node) {
++ if (table->group_addr.u.ip4 == key->ipv4.addr.dst) {
++ list_for_each_entry(entry, &table->entry_list, entry_node) {
++ skb_cpy = skb_copy(skb, GFP_ATOMIC);
++ if (!skb_cpy) {
++ kfree_skb(skb);
++ pr_err("%s(): error\n", __func__);
++ spin_unlock(&mdb->tbl_lock);
++ return;
++ }
++ memcpy(skb_cpy->data, entry->eth_addr, ETH_ALEN);
++ ovs_vport_send(vport, skb_cpy, ovs_key_mac_proto(key));
++ }
++ }
++ }
++ spin_unlock(&mdb->tbl_lock);
++ kfree_skb(skb);
++ } else
++ ovs_vport_send(vport, skb, ovs_key_mac_proto(key));
+ } else if (mru <= vport->dev->mtu) {
+ struct net *net = read_pnet(&dp->net);
+
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 4f097bd..e6be550 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -11,6 +11,7 @@
+ #include <linux/if_vlan.h>
+ #include <linux/in.h>
+ #include <linux/ip.h>
++#include <linux/igmp.h>
+ #include <linux/jhash.h>
+ #include <linux/delay.h>
+ #include <linux/time.h>
+@@ -530,6 +531,166 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
+ return err;
+ }
+
++static int ovs_ip4_multicast_add_group(__be32 _group_addr,
++ const u8 *entry_addr,
++ struct vport *input_vport)
++{
++ struct multicast_data_base *mdb;
++ struct multicast_table *table;
++ struct multicast_table_entry *entry;
++
++ if (ipv4_is_local_multicast(_group_addr))
++ return 0;
++
++ mdb = input_vport->mdb;
++ spin_lock(&mdb->tbl_lock);
++ list_for_each_entry(table, &mdb->list_head, mdb_node) {
++ if (table->group_addr.u.ip4 == _group_addr) {
++ list_for_each_entry(entry, &table->entry_list, entry_node) {
++ if (!memcmp(entry->eth_addr, entry_addr, ETH_ALEN)) {
++ spin_unlock(&mdb->tbl_lock);
++ return 0;
++ }
++ }
++ entry = kzalloc(sizeof(struct multicast_table_entry), GFP_ATOMIC);
++ if (!entry) {
++ spin_unlock(&mdb->tbl_lock);
++ return -ENOMEM;
++ }
++
++ memcpy(entry->eth_addr, entry_addr, ETH_ALEN);
++ list_add(&entry->entry_node, &table->entry_list);
++ spin_unlock(&mdb->tbl_lock);
++ return 0;
++ }
++ }
++
++ table = kzalloc(sizeof(struct multicast_table), GFP_ATOMIC);
++ if (!table) {
++ spin_unlock(&mdb->tbl_lock);
++ return -ENOMEM;
++ }
++
++ INIT_LIST_HEAD(&table->entry_list);
++ entry = kzalloc(sizeof(struct multicast_table_entry), GFP_ATOMIC);
++ if (!entry) {
++ kfree(table);
++ spin_unlock(&mdb->tbl_lock);
++ return -ENOMEM;
++ }
++
++ memcpy(entry->eth_addr, entry_addr, ETH_ALEN);
++ list_add(&entry->entry_node, &table->entry_list);
++
++ table->group_addr.u.ip4 = _group_addr;
++ list_add(&table->mdb_node, &mdb->list_head);
++
++ spin_unlock(&mdb->tbl_lock);
++ return 0;
++}
++
++static int ovs_ip4_multicast_leave_group(__be32 _group_addr,
++ const u8 *entry_addr,
++ struct vport *input_vport)
++{
++ struct multicast_data_base *mdb;
++ struct multicast_table *table, *table_tmp;
++ struct multicast_table_entry *entry, *entry_tmp;
++
++ if (ipv4_is_local_multicast(_group_addr))
++ return 0;
++
++ mdb = input_vport->mdb;
++ spin_lock(&mdb->tbl_lock);
++ list_for_each_entry_safe(table, table_tmp, &mdb->list_head, mdb_node) {
++ if (table->group_addr.u.ip4 == _group_addr) {
++ list_for_each_entry_safe(entry, entry_tmp, &table->entry_list, entry_node) {
++ if (!memcmp(entry->eth_addr, entry_addr, ETH_ALEN)) {
++ list_del(&entry->entry_node);
++ kfree(entry);
++
++ if (list_empty(&table->entry_list)) {
++ list_del(&table->mdb_node);
++ kfree(table);
++ }
++ spin_unlock(&mdb->tbl_lock);
++ return 0;
++ }
++ }
++ }
++ }
++ spin_unlock(&mdb->tbl_lock);
++ return 0;
++}
++
++static int ovs_multicast_ipv4_rcv(struct sk_buff *skb, struct vport *input_vport)
++{
++ struct ethhdr *eth_hdr;
++ const u8 *dl_src;
++ __be32 group_addr;
++ struct iphdr *ip_header;
++ struct igmphdr *igmp_hdr;
++ int i;
++ struct igmpv3_report *igmpv3_hdr;
++ u16 group_num;
++ struct igmpv3_grec *grec;
++ u8 group_type;
++ u8 aux_data_len;
++ u16 num_of_source;
++ int err;
++
++ err = ip_mc_check_igmp(skb);
++ if (err < 0)
++ return 0;
++
++ eth_hdr = skb_eth_hdr(skb);
++ dl_src = eth_hdr->h_source;
++ ip_header = (struct iphdr *)(skb->data + 14);
++ igmp_hdr = (struct igmphdr *)((u8 *)ip_header + ip_header->ihl * 4);
++
++ switch (igmp_hdr->type) {
++ case IGMP_HOST_MEMBERSHIP_REPORT:
++ case IGMPV2_HOST_MEMBERSHIP_REPORT:
++ group_addr = igmp_hdr->group;
++ ovs_ip4_multicast_add_group(group_addr, dl_src, input_vport);
++ break;
++ case IGMP_HOST_LEAVE_MESSAGE:
++ group_addr = igmp_hdr->group;
++ ovs_ip4_multicast_leave_group(group_addr, dl_src, input_vport);
++ break;
++ case IGMPV3_HOST_MEMBERSHIP_REPORT:
++ igmpv3_hdr = (struct igmpv3_report *)igmp_hdr;
++ group_num = ntohs(igmpv3_hdr->ngrec);
++ grec = igmpv3_hdr->grec;
++ //group_num = ntohs(*(u16 *)(igmp_hdr + 6));
++ //group = igmp_hdr + 8;
++ for (i = 0; i < group_num; i++) {
++ group_type = grec->grec_type;
++ aux_data_len = grec->grec_auxwords;
++ num_of_source = ntohs(grec->grec_nsrcs);
++ group_addr = grec->grec_mca;
++
++ if (group_type == IGMPV3_MODE_IS_EXCLUDE ||
++ group_type == IGMPV3_CHANGE_TO_EXCLUDE ||
++ group_type == IGMPV3_ALLOW_NEW_SOURCES)
++ ovs_ip4_multicast_add_group(group_addr, dl_src, input_vport);
++
++ if (group_type == IGMPV3_MODE_IS_INCLUDE ||
++ group_type == IGMPV3_CHANGE_TO_INCLUDE ||
++ group_type == IGMPV3_BLOCK_OLD_SOURCES)
++ if (num_of_source == 0)
++ ovs_ip4_multicast_leave_group(group_addr, dl_src, input_vport);
++
++ grec += (8 + (num_of_source * 4) + aux_data_len);
++ }
++ break;
++ default:
++ pr_warning("%s(): error pkt\n", __func__);
++ break;
++ }
++ return 0;
++}
++
+ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
+ {
+ struct ovs_header *ovs_header = info->userhdr;
+@@ -604,6 +765,9 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
+ OVS_CB(packet)->input_vport = input_vport;
+ sf_acts = rcu_dereference(flow->sf_acts);
+
++ if (is_igmp(packet))
++ ovs_multicast_ipv4_rcv(packet, input_vport);
++
+ local_bh_disable();
+ err = ovs_execute_actions(dp, packet, sf_acts, &flow->key);
+ local_bh_enable();
+@@ -2183,6 +2347,9 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
+ struct datapath *dp;
+ struct vport *vport;
+ unsigned int new_headroom;
++ struct multicast_data_base *mdb;
++ struct multicast_table *table, *table_tmp;
++ struct multicast_table_entry *entry, *entry_tmp;
+ int err;
+
+ reply = ovs_vport_cmd_alloc_info();
+@@ -2210,6 +2377,22 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
+ if (netdev_get_fwd_headroom(vport->dev) == dp->max_headroom)
+ update_headroom = true;
+
++ mdb = vport->mdb;
++ spin_lock(&mdb->tbl_lock);
++ list_for_each_entry_safe(table, table_tmp, &mdb->list_head, mdb_node) {
++ list_for_each_entry_safe(entry, entry_tmp, &table->entry_list, entry_node) {
++ list_del(&entry->entry_node);
++ kfree(entry);
++
++ if (list_empty(&table->entry_list)) {
++ list_del(&table->mdb_node);
++ kfree(table);
++ }
++ }
++ }
++ spin_unlock(&mdb->tbl_lock);
++ kfree(mdb);
++
+ netdev_reset_rx_headroom(vport->dev);
+ ovs_dp_detach_port(vport);
+
+diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
+index 81e85dd..520532e 100644
+--- a/net/openvswitch/datapath.h
++++ b/net/openvswitch/datapath.h
+@@ -215,6 +215,31 @@ static inline struct datapath *get_dp(struct net *net, int dp_ifindex)
+ return dp;
+ }
+
++#define IGMP_PROTOCOL_OFFSET 23
++/* support ipv4 for now */
++static inline bool is_ipv4_multicast(struct sk_buff *skb)
++{
++ struct ethhdr *eth_hdr = skb_eth_hdr(skb);
++
++ return eth_hdr->h_dest[0] == 0x01 && skb->protocol == htons(ETH_P_IP);
++}
++
++static inline bool is_igmp(struct sk_buff *skb)
++{
++ struct ethhdr *eth_hdr;
++
++ if (!skb)
++ return 0;
++
++ eth_hdr = skb_eth_hdr(skb);
++
++ if (eth_hdr->h_dest[0] == 0x01 &&
++ skb->protocol == htons(ETH_P_IP))
++ return (*(skb->data + IGMP_PROTOCOL_OFFSET) == IPPROTO_IGMP);
++ else
++ return 0;
++}
++
+ extern struct notifier_block ovs_dp_device_notifier;
+ extern struct genl_family dp_vport_genl_family;
+
+diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
+index 19af0ef..77bc923 100644
+--- a/net/openvswitch/vport.c
++++ b/net/openvswitch/vport.c
+@@ -141,6 +141,14 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
+ return ERR_PTR(-EINVAL);
+ }
+
++ vport->mdb = kzalloc(sizeof(struct multicast_data_base), GFP_KERNEL);
++ if (!vport->mdb) {
++ kfree(vport);
++ return ERR_PTR(-ENOMEM);
++ }
++ INIT_LIST_HEAD(&vport->mdb->list_head);
++ spin_lock_init(&vport->mdb->tbl_lock);
++
+ return vport;
+ }
+ EXPORT_SYMBOL_GPL(ovs_vport_alloc);
+diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
+index 1eb7495..eb69d6c 100644
+--- a/net/openvswitch/vport.h
++++ b/net/openvswitch/vport.h
+@@ -55,6 +55,30 @@ struct vport_portids {
+ u32 ids[];
+ };
+
++struct ip_addr {
++ union {
++ __be32 ip4;
++ struct in6_addr ip6;
++ } u;
++};
++
++struct multicast_table_entry {
++ struct list_head entry_node;
++ u8 eth_addr[ETH_ALEN];
++};
++
++struct multicast_table {
++ struct list_head mdb_node;
++ struct list_head entry_list;
++ struct ip_addr group_addr;
++};
++
++struct multicast_data_base {
++ struct list_head list_head;
++ spinlock_t tbl_lock;
++};
++
++
+ /**
+ * struct vport - one port within a datapath
+ * @dev: Pointer to net_device.
+@@ -79,6 +103,8 @@ struct vport {
+
+ struct list_head detach_list;
+ struct rcu_head rcu;
++
++ struct multicast_data_base *mdb;
+ };
+
+ /**
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 4c9012a..d63d381 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
@@ -108,7 +108,7 @@
file://747-net-phy-aquantia-add-AQR113C.patch \
file://748-add-netlink-support-for-dsa.patch \
file://749-net-dsa-support-mt7988.patch \
- file://750-add-mdio-bus-for-phy-node.patch \
+ file://750-add-mdio-bus-for-gphy-calibration.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 \
@@ -120,6 +120,7 @@
file://8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch \
file://8010-ovs-support-flow-offload.patch \
file://8010-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch \
+ file://8011-ovs-add-multicast-to-unicast-support.patch \
file://9000-PATCH-1-1-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch \
file://9001-PATCH-1-2-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch \
file://9002-PATCH-1-1-usb-add-embedded-Host-feature-support.patch \
diff --git a/recipes-kernel/linux/linux-mediatek_5.4.bb b/recipes-kernel/linux/linux-mediatek_5.4.bb
index f8f5f06..aecbc7d 100644
--- a/recipes-kernel/linux/linux-mediatek_5.4.bb
+++ b/recipes-kernel/linux/linux-mediatek_5.4.bb
@@ -7,8 +7,8 @@
KBRANCH ?= "linux-5.4.y"
-LINUX_VERSION ?= "5.4.215"
-SRCREV_machine ?= "6215647d9699cb8f1bf7333ec849242c4a9cf9a6"
+LINUX_VERSION ?= "5.4.219"
+SRCREV_machine ?= "fd92cfed8bc6668d314acd1e6da708a80826f768"
KMETA = "kernel-meta"
SRCREV_meta ?= "feeb59687bc0f054af837a5061f8d413ec7c93e9"
@@ -24,7 +24,9 @@
file://002-rdkb-mtd-ubi-relayout.patch;apply=no \
file://003-rdkb-mtd-kernel-ubi-relayout.patch;apply=no \
"
-
+SRC_URI_append_mt7988 += " \
+ file://mediatek/mt7988.cfg \
+"
SRC_URI_append_mt7986 += " \
file://mediatek/mt7986.cfg \
"