[Feature][ZXW-311] add lynq nv config support & merge changes for sihai

Only Configure :No
Affected branch: master
Affected module: uboot/ap
Is it affected on both ZXIC and MTK:only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: Ie02a4c5daad09441e82b92c9746d5aff0a603692
diff --git a/ap/app/Script/scripts/nat.sh b/ap/app/Script/scripts/nat.sh
old mode 100644
new mode 100755
index 1c9b82e..db36140
--- a/ap/app/Script/scripts/nat.sh
+++ b/ap/app/Script/scripts/nat.sh
@@ -6,6 +6,7 @@
 #
 
 path_sh=`nv get path_sh`
+rndis_ip_map=`cat /sys/class/lynq_nv_cfg/cdev_lynq_nv_cfg/rndis_ip_map`
 . $path_sh/global.sh
 echo "Info: nat.sh start " >> $test_log
 
@@ -18,7 +19,9 @@
 iptables -P FORWARD ACCEPT
 
 #clear nat
-iptables -t nat -F
+if [ "$rndis_ip_map" != "1" ];then
+	iptables -t nat -F
+fi
 iptables -t nat -X $ZTE_FORWARD_CHAIN
 iptables -t nat -X $ZTE_DMZ_CHAIN
 iptables -t nat -X $ZTE_MAPPING_CHAIN
@@ -29,6 +32,12 @@
 iptables -t nat -N $ZTE_DMZ_CHAIN
 iptables -t nat -N $ZTE_MAPPING_CHAIN
 
+if [ "$rndis_ip_map" == "1" ];then
+	iptables -t nat -D PREROUTING -j $ZTE_FORWARD_CHAIN
+	iptables -t nat -D PREROUTING -j $ZTE_DMZ_CHAIN
+	iptables -t nat -D PREROUTING -j $ZTE_MAPPING_CHAIN
+fi
+
 iptables -t nat -I PREROUTING 1 -j $ZTE_FORWARD_CHAIN
 iptables -t nat -I PREROUTING 1 -j $ZTE_DMZ_CHAIN
 iptables -t nat -I PREROUTING 1 -j $ZTE_MAPPING_CHAIN
diff --git a/ap/app/zte_comm/zte_mainctrl/netdev_proc.c b/ap/app/zte_comm/zte_mainctrl/netdev_proc.c
index a24b64c..367298f 100755
--- a/ap/app/zte_comm/zte_mainctrl/netdev_proc.c
+++ b/ap/app/zte_comm/zte_mainctrl/netdev_proc.c
@@ -871,16 +871,24 @@
 		{
 			char nat_enable[4] = {0};
 			
+			int rndis_ip_map = !system("cat /sys/class/lynq_nv_cfg/cdev_lynq_nv_cfg/rndis_ip_map | grep 1");
 			system_cmd_ex("iptables -P INPUT ACCEPT");
 			system_cmd_ex("iptables -P OUTPUT ACCEPT");
 			system_cmd_ex("iptables -P FORWARD ACCEPT");
-			system_cmd_ex("iptables -t nat -F");
+			if (rndis_ip_map == 0)
+				system_cmd_ex("iptables -t nat -F");
 			system_cmd_ex("iptables -t nat -X port_forward");
 			system_cmd_ex("iptables -t nat -X DMZ");
 			system_cmd_ex("iptables -t nat -X port_mapping");
 			system_cmd_ex("iptables -t nat -N port_forward");
 			system_cmd_ex("iptables -t nat -N DMZ");
 			system_cmd_ex("iptables -t nat -N port_mapping");
+			if (rndis_ip_map == 1)
+			{
+				system_cmd_ex("iptables -t nat -D PREROUTING -j port_forward");
+				system_cmd_ex("iptables -t nat -D PREROUTING -j DMZ");
+				system_cmd_ex("iptables -t nat -D PREROUTING -j port_mapping");
+			}
 			system_cmd_ex("iptables -t nat -I PREROUTING 1 -j port_forward");
 			system_cmd_ex("iptables -t nat -I PREROUTING 1 -j DMZ");
 			system_cmd_ex("iptables -t nat -I PREROUTING 1 -j port_mapping");
diff --git a/ap/app/zte_mdl/zte_mdl.c b/ap/app/zte_mdl/zte_mdl.c
index 38bb203..b883b2a 100755
--- a/ap/app/zte_mdl/zte_mdl.c
+++ b/ap/app/zte_mdl/zte_mdl.c
@@ -93,8 +93,13 @@
 }
 void wlan_entry(char *arg)
 {
-#if (defined _USE_VEHICLE_DC_REF)&&(defined _USE_VEHICLE_DC_REF_MMC0) //jb.qi add for wifi config on 20240301
-	wlan_main(0,NULL);
+#if (defined _USE_VEHICLE_DC_REF) //jb.qi add for wifi config on 20240301
+	if (system("cat /sys/class/lynq_nv_cfg/cdev_lynq_nv_cfg/wifi_enable | grep 1") == 0) {
+		wlan_main(0,NULL);
+	}
+	else{
+		printf("not need to start wifi\n");
+	}
 #endif
 	return;
 }
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/Makefile b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/Makefile
index 1d079c1..89aebac 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/Makefile
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/Makefile
@@ -10,7 +10,7 @@
 
 # CPU-specific support
 obj-$(CONFIG_ARCH_ZX297520V3)	+= io.o  irq.o board-zx297520v3.o spinlock.o pcu.o \
-                               		gpio.o debug.o reset.o pwr_ctrl.o 
+                               		gpio.o debug.o reset.o pwr_ctrl.o lynq_ap_nv_cfg.o
 obj-$(CONFIG_ARCH_ZX297520V3_EVB) += zx297520v3-evb-devices.o
 obj-$(CONFIG_ARCH_ZX297520V3_MDL) += zx297520v3-mdl-devices.o
 obj-$(CONFIG_ARCH_ZX297520V3_WATCH) += zx297520v3-watch-devices.o
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/board-zx297520v3.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/board-zx297520v3.c
index 929e125..2601f6e 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/board-zx297520v3.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/board-zx297520v3.c
@@ -669,6 +669,9 @@
 	pwr_buck3v3_on(POWER_WIFI);
 	printk("buck3v3 on, wifi power up.\n");
 #endif
+	//youchen@2024-06-20 add for lynq nv config begin
+	modify_zx29_device_table();
+	//youchen@2024-06-20 add for lynq nv config end
 	platform_add_devices(zx29_device_table, zx29_device_table_num);
 
 #if (defined CONFIG_SPI_ZX29) || (defined CONFIG_SPI_GPIO)
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/board.h b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/board.h
index 060569c..d6b6a32 100644
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/board.h
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/board.h
@@ -75,6 +75,9 @@
 
 extern struct platform_device *zx29_device_table[];
 extern unsigned int zx29_device_table_num;
+//youchen@2024-06-20 add for lynq nv config begin
+extern void modify_zx29_device_table();
+//youchen@2024-06-20 add for lynq nv config end
 
 void __init zx29_map_io(void);
 void __init zx29_clock_init(void);
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/iomap.h b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/iomap.h
index c721782..fe908c7 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/iomap.h
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/iomap.h
@@ -247,7 +247,12 @@
 

 #define SECURE_PUK_BASE						(POWERON_TYPE_BASE + 0xc)/*secure pub key 256byte*/

 #define WDT_IRAM_BASE						(SECURE_PUK_BASE + 0x100)/*wdt iram flag 36byte*/

-#define MMC_CFG_BASE						(WDT_IRAM_BASE+0x34)/*mmc flag 4Byte*/

+//youchen@2024-06-20 add for lynq nv config begin
+//#define MMC_CFG_BASE						(WDT_IRAM_BASE+0x34)/*mmc flag 4Byte*/

+#define MMC_LYNQ_NV_CFG_ADDR				(WDT_IRAM_BASE+0x34)/*mmc flag 1024Byte*/

+#define MMC_LYNQ_NV_CFG_SIZE				(0x100UL)
+//youchen@2024-06-20 add for lynq nv config end
+//
 /**************************************************************************************

  *                        iram: tsc

  **************************************************************************************/

diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/lynq_ap_nv_cfg.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/lynq_ap_nv_cfg.c
new file mode 100755
index 0000000..7fae817
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/lynq_ap_nv_cfg.c
@@ -0,0 +1,232 @@
+#include <linux/module.h>

+#include <linux/kernel.h>

+#include <linux/types.h>

+#include <linux/init.h>

+#include <linux/slab.h>

+#include <linux/device.h>

+#include <lynq/lynq_ap_nv_cfg.h>

+#include <linux/crc16.h>

+#include <mach/iomap.h>

+#include <linux/cdev.h>

+//#include <asm-generic/iomap.h>

+#include "lynq_default_nv_cfg.h"

+

+static struct nv_cfg_info * g_nv_cfg_info = NULL;

+

+static struct nv_cfg_info * get_valid_nv_cfg(unsigned char * buff, unsigned int len)

+{

+    int content_len, pos, crc;

+    unsigned char * p_cfg_body = NULL;

+    struct lynq_nv_cfg_header *p_tail;

+    struct version_info * p_versions;

+    struct lynq_nv_cfg * p_nv_cfg = (struct lynq_nv_cfg *)buff;

+    if (p_nv_cfg == NULL)

+        return NULL;

+    if (p_nv_cfg->head.magic_flag != 0xaa55 || p_nv_cfg->head.valid_flag != 1 ||

+            len < (p_nv_cfg->head.content_len + sizeof(struct lynq_nv_cfg_header)*2))

+    {

+        printk("got bad header\n");

+        return NULL;

+    }

+    content_len = (char*)&p_nv_cfg->tail - (char*)&p_nv_cfg->head - sizeof(struct lynq_nv_cfg_header);

+    //actual content len less than default request len, maybe a lower version protocol, ignore

+    if (content_len > p_nv_cfg->head.content_len || content_len != sizeof(lynq_nv_cfg_bitmap))

+    {

+        printk("got bad content len\n");

+        return NULL;

+    }

+    else if ( content_len == p_nv_cfg->head.content_len)

+    {

+        if (p_nv_cfg->tail.magic_flag != 0x55aa || p_nv_cfg->tail.valid_flag != 1

+                || p_nv_cfg->tail.content_len != p_nv_cfg->head.content_len)

+        {

+            printk("got bad tail %d\n", __LINE__);

+            return NULL;

+        }

+        p_cfg_body = (unsigned char*)kzalloc(p_nv_cfg->head.content_len, GFP_KERNEL);

+        memcpy(p_cfg_body, &p_nv_cfg->content, p_nv_cfg->head.content_len);

+        p_versions = p_nv_cfg->versions;

+    }

+    else // maybe a newer protocol, need backward compatible

+    {

+        p_cfg_body = (unsigned char*)&p_nv_cfg->content;

+        p_tail = (struct lynq_nv_cfg_header *)(p_cfg_body+p_nv_cfg->head.content_len);

+        if (p_tail->magic_flag != 0x55aa || p_tail->valid_flag != 1

+                || p_tail->content_len != p_nv_cfg->head.content_len)

+        {

+            printk("got bad tail %d\n", __LINE__);

+            return NULL;

+        }

+        p_versions = (struct version_info *)(p_cfg_body+p_nv_cfg->head.content_len + sizeof (struct lynq_nv_cfg_header));

+        p_cfg_body = (unsigned char*)kzalloc(p_nv_cfg->head.content_len, GFP_KERNEL);

+        memcpy(p_cfg_body, &p_nv_cfg->content, p_nv_cfg->head.content_len);

+    }

+

+    while(p_versions->soft_ver != 0 && p_versions->crc != 0)

+    {

+        if (p_versions->soft_ver != lynq_default_soft_version)

+        {

+            p_versions++;

+            continue;

+        }

+

+        //

+        for(pos = 0; pos < content_len; pos ++)

+        {

+            p_cfg_body[pos] &= lynq_nv_cfg_bitmap[pos];

+        }

+

+        crc = crc16(0, p_cfg_body, content_len);

+        printk("crc is %d\n", crc);

+

+        if (crc != p_versions->crc)

+        {

+            printk("got bad crc\n");

+            break;

+        }

+

+        return (struct nv_cfg_info *)p_cfg_body;

+    }

+

+    printk("no valid protocal version found\n");

+

+    if (p_cfg_body != NULL)

+    {

+        kfree(p_cfg_body);

+    }

+    return NULL;

+}

+

+static int read_from_uboot_memory(unsigned char * buff)

+{

+    int len, total_read_cnt, min_read_cnt, zero_cnt, ret;

+    int * curr_pos;

+    struct lynq_nv_cfg_header * head = (struct lynq_nv_cfg_header *)buff;

+    curr_pos = (int*)buff;

+    *curr_pos = ioread32(MMC_LYNQ_NV_CFG_ADDR);

+    printk("read data is %08x\n", *curr_pos);

+    curr_pos++;

+    if (head->magic_flag != 0xaa55 || head->valid_flag != 1

+            || head->content_len > (MMC_LYNQ_NV_CFG_SIZE - sizeof(struct lynq_nv_cfg_header)*2))

+    {

+        printk("got bad header len %d\n",head->content_len);

+        printk("magic %04x-need %04x\n", head->magic_flag, 0xaa55);

+        return 0;

+    }

+    min_read_cnt = head->content_len + sizeof(struct lynq_nv_cfg_header) + sizeof (struct version_info) + sizeof(int);

+    if (min_read_cnt > MMC_LYNQ_NV_CFG_SIZE)

+    {

+        total_read_cnt = MMC_LYNQ_NV_CFG_SIZE;

+        min_read_cnt = MMC_LYNQ_NV_CFG_SIZE;

+    }

+

+    total_read_cnt = total_read_cnt / sizeof (int);

+    min_read_cnt = min_read_cnt / sizeof (int);

+

+    len = 1;

+    zero_cnt = 0;

+    while(len < total_read_cnt && zero_cnt < 4)

+    {

+        ret = ioread32(MMC_LYNQ_NV_CFG_ADDR + len * sizeof(int));

+        printk("read data %08x\n", ret);

+        *curr_pos++ = ret;

+        if (ret != 0) {

+            zero_cnt = 0;

+        }

+        else{

+            zero_cnt ++;

+        }

+        len ++;

+    }

+

+    return len * sizeof(int);

+}

+

+struct nv_cfg_info *get_ap_nv_cfg_info()

+{

+

+    int len;

+    unsigned char * buff;

+    struct nv_cfg_info * ret;

+    printk("enter get_ap_nv_cfg_info\n");

+    if (g_nv_cfg_info != NULL)

+        return g_nv_cfg_info;

+

+    printk("[%s] start init!\n", __func__);

+

+    ret = NULL;

+    buff = kzalloc(MMC_LYNQ_NV_CFG_SIZE, GFP_KERNEL);

+    printk("enter read_from_uboot_memory\n");

+    len = read_from_uboot_memory(buff);

+    if (len > 0)

+    {

+        printk("enter check cfg from uboot\n");

+        ret = get_valid_nv_cfg(buff, len);

+    }

+    // read default in head file

+    if (ret == NULL)

+    {

+        printk("enter check lynq_default_nv_cfg_value\n");

+        ret = get_valid_nv_cfg(lynq_default_nv_cfg_value, sizeof (lynq_default_nv_cfg_value));

+    }

+

+    // use local default values

+    if (ret == NULL){

+        printk("enter use local default values\n");

+        ret = (struct nv_cfg_info *)kzalloc(sizeof (struct nv_cfg_info), GFP_KERNEL);

+        memset(ret, 0, sizeof(struct nv_cfg_info));

+        ret->mmc0_enable = 1;

+        ret->mmc1_enable = 1;

+    }

+

+    g_nv_cfg_info = ret;

+

+    return ret;

+}

+

+#define DECLARE_NV_CFG_ATTR(name) \

+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \

+{ \

+    return sprintf(buf, "%d", get_##name()); \

+}\

+\

+static DEVICE_ATTR(name, 0664, name##_show, NULL); \

+

+

+DECLARE_NV_CFG_ATTR(wifi_enable)

+DECLARE_NV_CFG_ATTR(rndis_ip_map)

+/*

+static struct attribute * lynq_nv_cfg_attrs[] = {

+    &dev_attr_wifi_enable.attr,

+    NULL,

+};

+

+static const struct attribute_group lynq_nv_cfg_attr_grp = {

+    .attrs = lynq_nv_cfg_attrs,

+};

+*/

+static struct class * lynq_nv_cfg_class;

+static struct class_device * lynq_nv_cfg_device;

+static int __init lynq_nv_cfg_init(void)

+{

+    printk("[%s] start init!\n", __func__);

+    lynq_nv_cfg_class =  class_create(THIS_MODULE, "lynq_nv_cfg");

+    if (lynq_nv_cfg_class == NULL)

+        return -1;

+    lynq_nv_cfg_device = device_create(lynq_nv_cfg_class, NULL, MKDEV(1,0), NULL, "cdev_lynq_nv_cfg");

+    if (lynq_nv_cfg_device == NULL)

+        return -1;

+    //sysfs_create_group(&lynq_nv_cfg_device->kobj, &lynq_nv_cfg_attr_grp);

+    device_create_file(lynq_nv_cfg_device, &dev_attr_wifi_enable);

+    device_create_file(lynq_nv_cfg_device, &dev_attr_rndis_ip_map);

+    return 0;

+}

+

+static void __exit lynq_nv_cfg_exit(void)

+{

+    printk("[%s] start exit!\n", __func__);

+    //platform_driver_unregister(&lynq_nv_cfg_device);

+}

+

+module_init(lynq_nv_cfg_init);

+module_exit(lynq_nv_cfg_exit);

diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/lynq_default_nv_cfg.h b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/lynq_default_nv_cfg.h
new file mode 100755
index 0000000..85ebb80
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/lynq_default_nv_cfg.h
@@ -0,0 +1,18 @@
+#ifndef LYNQ_DEFAULT_NV_CFG_H

+#define LYNQ_DEFAULT_NV_CFG_H

+

+static const char lynq_default_nv_cfg_value1[] = {

+    '\x55', '\xaa', '\x0b', '\x00', '\xff', '\xff', '\xff', '\xff', '\x00', '\xaa', '\x55', '\x0b', '\x00', '\x05', '\x10', '\x0c', '\x03'

+};

+

+static const char lynq_default_nv_cfg_value[] = {

+    '\x55', '\xaa', '\x09', '\x00', '\xc0', '\x80', '\x80', '\x00', '\xaa', '\x55', '\x09', '\x00', '\x05', '\x10', '\x0c', '\x03'

+};

+

+static const char lynq_nv_cfg_bitmap[] = {

+    '\xC0', '\x80', '\x80', '\x80'

+};

+

+static int lynq_default_soft_version = 1;

+

+#endif // LYNQ_DEFAULT_NV_CFG_H

diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pwr_ctrl.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pwr_ctrl.c
index e5ec161..0ba80af 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pwr_ctrl.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pwr_ctrl.c
@@ -29,6 +29,10 @@
 //++yuwei 20160719
 #include <mach/gpio_cfg.h>
 //++
+//youchen@2024-06-20 add for lynq nv config begin
+#include <lynq/lynq_ap_nv_cfg.h>
+//youchen@2024-06-20 add for lynq nv config end
+
 
 static unsigned int pwr_buck3v3_init_flag	= 0;
 static unsigned int pwr_buck3v3_status  		= 0;
@@ -287,7 +291,7 @@
 	   }
 
 	   // zw.wang The WiFi-related control pins gpio132 and gpio91 are still affected after the uboot removes mmc0 on 20240531 on start
-	   if ((ioread32(MMC_CFG_BASE) & (1 << 0)))
+	   if (get_mmc0_enable() == 1)
 	   {
 		   gpio_direction_output(ZX29_GPIO_132, 1);
 		   gpio_direction_output(ZX29_GPIO_91, 1);
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c
index 485d8f2..74cba0d 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c
@@ -64,6 +64,9 @@
 #endif
 #include <mach/gpio_cfg.h>
 
+//youchen@2024-06-20 add for lynq nv config begin
+#include <lynq/lynq_ap_nv_cfg.h>
+//youchen@2024-06-20 add for lynq nv config end
 
 struct zx29_uart_platdata  zx29_uart0_platdata= {
 		.uart_use = 1,
@@ -1149,7 +1152,7 @@
 #endif
 
 #ifdef CONFIG_MMC_ZX29
-#if (defined _USE_VEHICLE_DC_REF)&&(defined _USE_VEHICLE_DC_REF_MMC0) //jb.qi add for wifi config on 20240221
+#if (defined _USE_VEHICLE_DC_REF) //jb.qi add for wifi config on 20240221
     &zx29_sdmmc0_device,
 #endif
     &zx29_sdmmc1_device,
@@ -1232,6 +1235,37 @@
 
 unsigned int zx29_device_table_num=ARRAY_SIZE(zx29_device_table);
 
+//youchen@2024-06-20 add for lynq nv config begin
+void modify_zx29_device_table()
+{
+#if (defined _USE_VEHICLE_DC_REF) 
+	int i, last;
+
+	last = 0;
+	for( i=0; i<zx29_device_table_num;i++ )
+	{
+		if (zx29_device_table[i] == &zx29_sdmmc0_device && get_mmc0_enable() == 0)
+		{
+			continue;
+		}
+		else if (zx29_device_table[i] == &zx29_sdmmc1_device && get_mmc1_enable() == 0)
+		{
+			continue;
+		}
+		else if (i != last)
+		{
+			zx29_device_table[last++] = zx29_device_table[i];
+		}
+		else
+		{
+			last++;
+		}
+	}
+	zx29_device_table_num -= (i - last);
+#endif
+}
+//youchen@2024-06-20 add for lynq nv config end
+
 #if (defined CONFIG_SPI_ZX29) || (defined CONFIG_SPI_GPIO)
 struct zx29_lcd_platform_data lead_lcd_platform = {
 	.spi_dcx_gpio = PIN_SPI_DCX,
diff --git a/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc-pltfm.c b/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc-pltfm.c
index 0cf0d7f..1100d88 100755
--- a/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc-pltfm.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc-pltfm.c
@@ -44,6 +44,11 @@
 static struct dw_mci *dw_mci_host_ptr[2];
 volatile u8 mmc0_data1_flag = 0xff;
 //zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on end
+
+//youchen@2024-06-20 add for lynq nv config begin
+#include <lynq/lynq_ap_nv_cfg.h>
+//youchen@2024-06-20 add for lynq nv config end
+
 static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
@@ -551,7 +556,8 @@
 #endif
 
 #ifdef _USE_VEHICLE_DC
-	if(ioread32(MMC_CFG_BASE)&(1<<pdev->id)){
+	//youchen@2024-06-20 add for lynq nv config
+	if((0 == pdev->id && get_mmc0_enable() == 1) || (1 == pdev->id && get_mmc1_enable() == 1)){
 		return dw_mci_pltfm_register(pdev, drv_data);
 	}else
 	{
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/wifi_dev_aic88.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/wifi_dev_aic88.c
index a020bbc..18b3a9c 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/wifi_dev_aic88.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/wifi_dev_aic88.c
@@ -6,7 +6,7 @@
 #include <asm/uaccess.h>
 #include <linux/slab.h>
 //zw.wang The WiFi-related control pins gpio132 and gpio91 are still affected after the uboot removes mmc0 on 20240531 on start
-#include <mach/iomap.h>
+#include <lynq/lynq_ap_nv_cfg.h>
 //zw.wang The WiFi-related control pins gpio132 and gpio91 are still affected after the uboot removes mmc0 on 20240531 on end
 
 #define WIFI_IOCTL_STOP   0x0
@@ -51,7 +51,7 @@
 	int ret = 0;
 	void __user *argp = (void __user *) arg;
 	//zw.wang The WiFi-related control pins gpio132 and gpio91 are still affected after the uboot removes mmc0 on 20240531 on start
-	if(!(ioread32(MMC_CFG_BASE)&(1<<0)))
+	if(!get_mmc0_enable() || !get_wifi_enable())
         return -ENODEV;
 	//zw.wang The WiFi-related control pins gpio132 and gpio91 are still affected after the uboot removes mmc0 on 20240531 on end
 	switch (cmd) {
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/u_ether.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/u_ether.c
index 5f9d709..16cf5dc 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/u_ether.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/u_ether.c
@@ -26,6 +26,10 @@
 #include "multi_packet.h"
 #include <mach/highspeed_debug.h>
 #include <linux/nvro_comm.h>
+//youchen@2024-06-20 add for lynq nv config begin
+#include <lynq/lynq_ap_nv_cfg.h>
+//youchen@2024-06-20 add for lynq nv config end
+
 /*
  * This component encapsulates the Ethernet link glue needed to provide
  * one (!) network link through the USB gadget stack, normally "usb0".
@@ -1007,6 +1011,13 @@
 	{0x34,0x4b,0x50,0x00,0x00,0x0a},
 	{0x34,0x4b,0x50,0x00,0x00,0x0b},
 	{0x34,0x4b,0x50,0x00,0x00,0x0c}};
+//youchen@2024-06-20 add for lynq nv config begin
+static u8 eth_addrs2[ETH_MAX_NUM][ETH_ALEN] = {
+	{0x3a,0x4b,0x50,0x00,0x00,0x00},
+	{0x34,0x4b,0x50,0x00,0x00,0x0a},
+	{0x34,0x4b,0x50,0x00,0x00,0x0b},
+	{0x34,0x4b,0x50,0x00,0x00,0x0c}};
+//youchen@2024-06-20 add for lynq nv config end
 #define NVUSB_MAC_LEN 6
 
 
@@ -1323,7 +1334,17 @@
     {
     	random_ether_addr(net->dev_addr);
 	usb_printk("random_ether_addr ok\n");
-	host_addr = &eth_addrs[num][0];
+	//youchen@2024-06-20 add for lynq nv config begin
+	if (get_rndis_mac_convert() == 1)
+	{
+		host_addr = &eth_addrs2[num][0];
+		printk("rndis_mac_convert finish\n");
+	}
+	else
+	{
+		host_addr = &eth_addrs[num][0];
+	}
+	//youchen@2024-06-20 add for lynq nv config end
 	memcpy(dev->host_mac, host_addr, ETH_ALEN);
 
 	if (ethaddr)
diff --git a/ap/os/linux/linux-3.4.x/include/lynq/lynq_ap_nv_cfg.h b/ap/os/linux/linux-3.4.x/include/lynq/lynq_ap_nv_cfg.h
new file mode 100755
index 0000000..e13fb05
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/include/lynq/lynq_ap_nv_cfg.h
@@ -0,0 +1,61 @@
+#ifndef LYNQ_AP_NV_CFG_H

+#define LYNQ_AP_NV_CFG_H

+

+#pragma pack(1)

+struct lynq_nv_cfg_header

+{

+    unsigned short magic_flag;

+    unsigned short valid_flag:1;

+    unsigned short content_len:15;

+};

+struct nv_cfg_info{

+    unsigned char reserved_0:6;

+    unsigned char mmc1_enable:1;

+    unsigned char mmc0_enable:1;

+    unsigned char reserved_1:7;

+    unsigned char wifi_enable:1;

+    unsigned char reserved_2:7;

+    unsigned char rndis_mac_convert:1;

+    unsigned char reserved_3:7;

+    unsigned char rndis_ip_map:1;

+};

+

+struct version_info{

+    unsigned short soft_ver:12;

+    unsigned short hard_ver:4;

+    unsigned short crc;

+};

+

+struct lynq_nv_cfg

+{

+    struct lynq_nv_cfg_header head;

+    struct nv_cfg_info content;

+    struct lynq_nv_cfg_header tail;

+    struct version_info versions[0];

+};

+

+#pragma pack()

+

+extern struct nv_cfg_info *get_ap_nv_cfg_info();

+

+static inline int get_mmc0_enable() {

+    return get_ap_nv_cfg_info()->mmc0_enable;

+}

+

+static inline int get_mmc1_enable() {

+    return get_ap_nv_cfg_info()->mmc1_enable;

+}

+

+static inline int get_wifi_enable() {

+    return get_ap_nv_cfg_info()->wifi_enable;

+}

+

+static inline int get_rndis_mac_convert() {

+    return get_ap_nv_cfg_info()->rndis_mac_convert;

+}

+

+static inline int get_rndis_ip_map() {

+    return get_ap_nv_cfg_info()->rndis_ip_map;

+}

+

+#endif // LYNQ_AP_NV_CFG_H

diff --git a/boot/common/src/uboot/drivers/peripheral/Makefile b/boot/common/src/uboot/drivers/peripheral/Makefile
index 103b373..2f058a9 100755
--- a/boot/common/src/uboot/drivers/peripheral/Makefile
+++ b/boot/common/src/uboot/drivers/peripheral/Makefile
@@ -42,6 +42,8 @@
 COBJS-$(CONFIG_ZX297520V3E_MDL_AB)	+= peripheral.o
 COBJS-$(CONFIG_ZX297520V3E_VEHICLE_DC)	+= peripheral.o
 COBJS-$(CONFIG_ZX297520V3E_VEHICLE_DC_REF)	+= peripheral.o
+COBJS-$(CONFIG_ZX297520V3E_VEHICLE_DC_REF)	+= lynq_uboot_nv_cfg.o
+COBJS-$(CONFIG_ZX297520V3E_VEHICLE_DC_REF)	+= oem_nv_cfg.o
 
 COBJS	:= $(sort $(COBJS-y))
 SRCS	:= $(COBJS:.o=.c)
diff --git a/boot/common/src/uboot/drivers/peripheral/lynq_uboot_nv_cfg.c b/boot/common/src/uboot/drivers/peripheral/lynq_uboot_nv_cfg.c
new file mode 100755
index 0000000..36fe651
--- /dev/null
+++ b/boot/common/src/uboot/drivers/peripheral/lynq_uboot_nv_cfg.c
@@ -0,0 +1,194 @@
+#include <dma_cfg.h>
+
+#ifdef LYNQ_NV_CFG_SUPPORT
+
+#include "../rsa/drv_rsa.h"
+#include "../hash/drv_hash.h"
+#include "lynq_uboot_nv_cfg.h"
+
+#define LYNQ_ERROR(t) do{BOOT_PRINTF(UBOOT_NOTICE, t);}while(0)
+
+#define DEBUG_LYNQ_NV_CFG 1
+
+#ifdef DEBUG_LYNQ_NV_CFG
+void lynq_hex_display(u32 * buff, int len)
+{
+    int i, pos;
+    char * txt_buffer = malloc(4096);
+    memset(txt_buffer, 0, 4096);
+    pos = 0;
+    BOOT_PRINTF(UBOOT_NOTICE, "display data begin:\n");
+    for(i=0;i<len;i++)
+    {
+        pos += sprintf(txt_buffer+pos, "%08x", buff[i]);
+        //BOOT_PRINTF(UBOOT_NOTICE, "%08x ", buff[i]);
+        if (i % 8 == 7 )
+        {
+            BOOT_PRINTF(UBOOT_NOTICE, "%s\n", txt_buffer);
+            memset(txt_buffer, 0, 4096);
+            pos = 0;
+        }
+    }
+    BOOT_PRINTF(UBOOT_NOTICE, "%s\n", txt_buffer);
+    free(txt_buffer);
+}
+#define LYNQ_DEBUG(t) do{BOOT_PRINTF(UBOOT_NOTICE, t);}while(0)
+#else
+#define lynq_hex_display(...) do{}while(0)
+#define LYNQ_DEBUG(t) do{}while(0)
+#endif
+
+int check_lynq_nv_cfg(void)
+{
+    struct lynq_nv_cfg * tmp_cfg;
+    int content_len, pos, len, x;
+    T_Rsa_Paramter sRSAInput;
+    u32 uiRet = -1;
+    u32 uiHashResArr[4] = {0};
+    u32 uiHashResLen = 0;
+    u32 uiRsaResArr[RSA_U32_LEN] = {0};
+    u32 puiArrPubKey[RSA_U32_LEN*2] = {0};
+    u32 *puiRsaResAddr = NULL;
+    char * tmp_buffer = malloc(MMC_LYNQ_NV_CFG_SIZE*3);
+    memset(tmp_buffer, 0 , MMC_LYNQ_NV_CFG_SIZE*3);
+    tmp_cfg = (struct lynq_nv_cfg *)tmp_buffer;
+    if (sizeof (lynq_nv_cfg_bitmap) <= 0 || sizeof (lynq_nv_cfg_bitmap) != sizeof (oem_nv_cfg_bitmap))
+    {
+        LYNQ_ERROR("got bad bitmap\n");
+        goto fail_exit;
+    }
+    if (sizeof (lynq_nv_cfg_publickey) != LYNQ_NV_CFG_PUBLICKEY_LEN)
+    {
+        LYNQ_ERROR("got bad public key\n");
+        goto fail_exit;
+    }
+    if (sizeof (lynq_nv_cfg_sign) != LYNQ_NV_CFG_SIGN_LEN )
+    {
+        LYNQ_ERROR("got bad sign\n");
+        goto fail_exit;
+    }
+    if (sizeof(lynq_nv_cfg_value) == sizeof(struct lynq_nv_cfg))
+    {
+        pos = 0;
+        len = sizeof(lynq_nv_cfg_value);
+        memcpy(tmp_cfg, lynq_nv_cfg_value, len);
+        pos += len;
+        content_len = ((char*)&tmp_cfg->tail - (char*)&tmp_cfg->head) - sizeof(struct lynq_nv_cfg_header);
+
+        if (tmp_cfg->head.magic_flag == 0xaa55 && tmp_cfg->tail.magic_flag == 0x55aa
+                && tmp_cfg->head.content_len == content_len  && tmp_cfg->tail.content_len == content_len
+                && tmp_cfg->head.valid_flag == 1 && tmp_cfg->tail.valid_flag == 1)
+        {
+            len = sizeof (lynq_nv_cfg_version);
+            memcpy(tmp_buffer+pos, lynq_nv_cfg_version, len);
+            pos += len;
+
+            len = sizeof (lynq_nv_cfg_bitmap);
+            memcpy(tmp_buffer+pos, lynq_nv_cfg_bitmap, len);
+            pos += len;
+
+            len = sizeof (oem_nv_cfg_bitmap);
+            memcpy(tmp_buffer+pos, oem_nv_cfg_bitmap, len);
+            pos += len;
+
+            for(x=0; x < sizeof(lynq_nv_cfg_bitmap); x++)
+            {
+                tmp_cfg->content[x] &= lynq_nv_cfg_bitmap[x];
+            }
+
+            memcpy(puiArrPubKey, lynq_nv_cfg_publickey, RSA_BYTE_LEN);
+            memcpy((puiArrPubKey+(RSA_U32_LEN*2 -1)), lynq_nv_cfg_publickey + RSA_BYTE_LEN, sizeof(u32));
+            sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;
+            sRSAInput.udNbitLen = RAS_BIT_LEN;
+            sRSAInput.udEbitLen = RAS_BIT_LEN;
+            sRSAInput.pudInputM = (u32*)lynq_nv_cfg_sign;
+            sRSAInput.pudInputE = (u32*)puiArrPubKey + RSA_U32_LEN;
+            sRSAInput.pudInputN = ((u32*)puiArrPubKey);
+            sRSAInput.pudOutputP = uiRsaResArr;
+
+            lynq_hex_display(sRSAInput.pudInputE, RSA_U32_LEN);
+            lynq_hex_display(sRSAInput.pudInputN, RSA_U32_LEN);
+            lynq_hex_display(sRSAInput.pudInputM, RSA_U32_LEN);
+
+            uiRet = Rsa_Calculate(sRSAInput);
+            if(uiRet != 0)
+            {
+                LYNQ_ERROR("calc rsa fail\n");
+                goto fail_exit;
+            }
+
+            lynq_hex_display(uiRsaResArr, RSA_U32_LEN);
+
+            uiRet = Hash_Calculate(HASH_MODE_MD5,
+                                   HASH_SMALL_ENDIAN,
+                                   (u32*)tmp_buffer,
+                                   pos,
+                                   NULL,
+                                   0,
+                                   uiHashResArr,
+                                   &uiHashResLen);
+            if(uiRet != 0)
+            {
+                LYNQ_ERROR("calc hash fail\n");
+                goto fail_exit;
+            }
+            lynq_hex_display(uiHashResArr, uiHashResLen);
+
+            puiRsaResAddr = sRSAInput.pudOutputP + (RSA_U32_LEN - uiHashResLen);
+
+            if (memcmp(puiRsaResAddr, uiHashResArr, uiHashResLen*sizeof (u32)) != 0)
+            {
+                LYNQ_ERROR("not valid sign\n");
+                goto fail_exit;
+            }
+        }
+        else
+        {
+            LYNQ_ERROR("not valid head\n");
+            goto fail_exit;
+        }
+    }
+    else
+    {
+        LYNQ_ERROR("not valid cfg\n");
+        goto fail_exit;
+    }
+
+    free(tmp_buffer);
+//    for (x=0;x<10;x++)
+//        udelay (600000);
+//    LYNQ_ERROR("cy: lynq_setup_nv_cfg\n");
+    return 0;
+fail_exit:
+    free(tmp_buffer);
+    return -1;
+}
+
+extern char* get_oem_nv_cfg(void);
+void lynq_setup_nv_cfg(void)
+{
+    char * oem_cfg_buff;
+    memset((void*)MMC_LYNQ_NV_CFG_ADDR, 0, MMC_LYNQ_NV_CFG_SIZE);
+    if (sizeof(lynq_nv_cfg_value) <= MMC_LYNQ_NV_CFG_SIZE && check_lynq_nv_cfg() == 0)
+    {
+        oem_cfg_buff = get_oem_nv_cfg();
+        if (oem_cfg_buff != NULL)
+        {
+            memcpy((void*)MMC_LYNQ_NV_CFG_ADDR, oem_cfg_buff, sizeof(lynq_nv_cfg_value));
+            free(oem_cfg_buff);
+            LYNQ_DEBUG("using oem nv cfg\n");
+        }
+        else
+        {
+            memcpy((void*)MMC_LYNQ_NV_CFG_ADDR, lynq_nv_cfg_value, sizeof(lynq_nv_cfg_value));
+            LYNQ_DEBUG("using lynq nv cfg\n");
+        }
+    }
+    else
+    {
+        LYNQ_ERROR("lynq_setup_nv_cfg no valid nv config\n");
+    }
+}
+
+#endif
+
diff --git a/boot/common/src/uboot/drivers/peripheral/lynq_uboot_nv_cfg.h b/boot/common/src/uboot/drivers/peripheral/lynq_uboot_nv_cfg.h
new file mode 100755
index 0000000..d2f0da9
--- /dev/null
+++ b/boot/common/src/uboot/drivers/peripheral/lynq_uboot_nv_cfg.h
@@ -0,0 +1,60 @@
+#ifndef __LYNQ_UBOOT_NV_CFG__H__
+#define __LYNQ_UBOOT_NV_CFG__H__
+
+#define RAS_BIT_LEN 1024
+#define RSA_BYTE_LEN (RAS_BIT_LEN / 8)
+#define RSA_U32_LEN (RSA_BYTE_LEN / sizeof(u32))
+#define LYNQ_NV_CFG_SIGN_LEN RSA_BYTE_LEN
+#define LYNQ_NV_CFG_PUBLICKEY_LEN (RSA_BYTE_LEN + sizeof(u32))
+
+#pragma pack(1)
+
+struct lynq_nv_cfg_header
+{
+    unsigned short magic_flag;
+    unsigned short valid_flag:1;
+    unsigned short content_len:15;
+};
+struct lynq_nv_cfg
+{
+    struct lynq_nv_cfg_header head;
+    unsigned char content[4];
+    struct lynq_nv_cfg_header tail;
+    unsigned int lynq_reserved[1];
+};
+#pragma pack()
+
+static const char lynq_nv_cfg_version[] = "T106_CN_20240617";
+static const char lynq_nv_cfg_value[] = {
+   '\x55', '\xaa', '\x09', '\x00', '\xc0', '\x00', '\x00', '\x00', '\xaa', '\x55', '\x09', '\x00', '\x01', '\x00', '\x3c', '\x00'
+};
+
+static const char lynq_nv_cfg_bitmap[] = {
+    '\xC0', '\x80', '\x80', '\x80'
+};
+static const char oem_nv_cfg_bitmap[] = {
+    '\x40', '\x80', '\x80', '\x80'
+};
+static const char lynq_nv_cfg_publickey[] = {
+    '\x92', '\x95', '\xf0', '\xc7', '\x36', '\x68', '\xad', '\xd0', '\x0f', '\xdb', '\x5c', '\xfd', '\x58', '\xf0', '\xc0', '\xa0',
+    '\x0b', '\x89', '\x6b', '\xa0', '\x05', '\x93', '\xa9', '\xb3', '\x54', '\x0f', '\x68', '\x24', '\x3e', '\x2d', '\xfd', '\x02',
+    '\x05', '\xf7', '\xe7', '\x48', '\xad', '\x39', '\x13', '\x6f', '\x71', '\xef', '\x6e', '\xcf', '\xc6', '\xcf', '\x5f', '\xc9',
+    '\x24', '\xa2', '\xd8', '\x2d', '\x17', '\xd6', '\x2b', '\x96', '\x7b', '\x48', '\x98', '\x12', '\xd5', '\x28', '\x4c', '\x72',
+    '\xcd', '\x34', '\xd5', '\xdb', '\x89', '\x87', '\x34', '\xe2', '\xab', '\x29', '\xe4', '\x56', '\x40', '\xe5', '\x92', '\x76',
+    '\xa5', '\xee', '\xb4', '\xbc', '\x37', '\x93', '\xb7', '\xe4', '\x30', '\x4d', '\x92', '\x7b', '\x2c', '\x11', '\x94', '\xd9',
+    '\x8b', '\xe8', '\x0d', '\x96', '\xed', '\x64', '\xd1', '\x0a', '\x7d', '\x4a', '\xd8', '\x1b', '\xf5', '\x0f', '\x4c', '\xfb',
+    '\x07', '\xde', '\xfa', '\xf9', '\xae', '\x42', '\x68', '\x6d', '\xe9', '\xe4', '\x58', '\x80', '\xdb', '\x0b', '\x84', '\xab',
+    '\x01', '\x00', '\x01', '\x00'
+};
+static const char lynq_nv_cfg_sign[] = {
+    '\xef', '\x87', '\xd6', '\x86', '\xea', '\xe6', '\x7f', '\xbd', '\x01', '\x57', '\xe4', '\x94', '\xfa', '\x86', '\xcd', '\xdb',
+    '\x75', '\xe2', '\xc0', '\x94', '\xe0', '\x3f', '\x30', '\x90', '\x9d', '\x24', '\x6e', '\x29', '\x8f', '\x90', '\x52', '\x86',
+    '\x19', '\xfc', '\x83', '\x7f', '\x1d', '\x9f', '\x32', '\x4b', '\xb9', '\x01', '\x5d', '\xb3', '\xf3', '\xcd', '\x30', '\xc5',
+    '\xf6', '\x2f', '\xc5', '\x68', '\x7e', '\x87', '\xae', '\xf2', '\x70', '\x54', '\xff', '\xe6', '\x60', '\xcb', '\xfe', '\xec',
+    '\x68', '\xaa', '\x01', '\x49', '\xd2', '\x93', '\x7b', '\x6e', '\x31', '\x0f', '\x91', '\xad', '\xdf', '\x81', '\x62', '\x04',
+    '\x36', '\x21', '\x22', '\xb6', '\x79', '\xfd', '\x61', '\xcf', '\x3a', '\xb9', '\x40', '\xba', '\x7c', '\xdf', '\x6e', '\xba',
+    '\x1e', '\xc2', '\x27', '\xb9', '\x49', '\x35', '\xd6', '\x5d', '\xc9', '\xe5', '\xed', '\x27', '\xa4', '\x70', '\x59', '\x41',
+    '\x4c', '\x84', '\x72', '\x7a', '\x06', '\xc7', '\x16', '\xcb', '\x56', '\x6a', '\x39', '\xeb', '\x0f', '\xa9', '\x59', '\xcc'
+};
+
+#endif
diff --git a/boot/common/src/uboot/drivers/peripheral/oem_nv_cfg.c b/boot/common/src/uboot/drivers/peripheral/oem_nv_cfg.c
new file mode 100755
index 0000000..0893035
--- /dev/null
+++ b/boot/common/src/uboot/drivers/peripheral/oem_nv_cfg.c
@@ -0,0 +1,141 @@
+#include <dma_cfg.h>
+
+
+#ifdef LYNQ_NV_CFG_SUPPORT
+#include "../rsa/drv_rsa.h"
+#include "../hash/drv_hash.h"
+#include "lynq_uboot_nv_cfg.h"
+#include "oem_nv_cfg.h"
+
+#define LYNQ_ERROR(t) do{BOOT_PRINTF(UBOOT_NOTICE, t);}while(0)
+
+#define DEBUG_LYNQ_NV_CFG 1
+
+#ifdef DEBUG_LYNQ_NV_CFG
+#define LYNQ_DEBUG(t) do{BOOT_PRINTF(UBOOT_NOTICE, t);}while(0)
+extern void lynq_hex_display(u32 * buff, int len);
+#else
+#define lynq_hex_display(...) do{}while(0)
+#define LYNQ_DEBUG(t) do{}while(0)
+#endif
+
+char* get_oem_nv_cfg(void)
+{
+    struct lynq_nv_cfg * oem_cfg, *lynq_cfg;
+    int content_len, pos, len, x;
+    T_Rsa_Paramter sRSAInput;
+    u32 uiRet = -1;
+    u32 uiHashResArr[4] = {0};
+    u32 uiHashResLen = 0;
+    u32 uiRsaResArr[RSA_U32_LEN] = {0};
+    u32 puiArrPubKey[RSA_U32_LEN*2] = {0};
+    u32 *puiRsaResAddr = NULL;
+    char * tmp_buffer = malloc(MMC_LYNQ_NV_CFG_SIZE*3);
+    memset(tmp_buffer, 0 , MMC_LYNQ_NV_CFG_SIZE*3);
+    oem_cfg = (struct lynq_nv_cfg *)tmp_buffer;
+    lynq_cfg = (struct lynq_nv_cfg *)lynq_nv_cfg_value;
+    if (sizeof (oem_nv_cfg_publickey) != LYNQ_NV_CFG_PUBLICKEY_LEN)
+    {
+        LYNQ_ERROR("got bad oem public key\n");
+        goto fail_exit;
+    }
+    if (sizeof (oem_nv_cfg_sign) != LYNQ_NV_CFG_SIGN_LEN )
+    {
+        LYNQ_ERROR("got bad oem sign\n");
+        goto fail_exit;
+    }
+    if (sizeof(oem_nv_cfg_value) == sizeof(struct lynq_nv_cfg))
+    {
+        pos = 0;
+        len = sizeof(oem_nv_cfg_value);
+        memcpy(oem_cfg, oem_nv_cfg_value, len);
+        pos += len;
+        content_len = ((char*)&oem_cfg->tail - (char*)&oem_cfg->head) - sizeof (struct lynq_nv_cfg_header);
+        if (oem_cfg->head.magic_flag == 0xaa55 && oem_cfg->tail.magic_flag == 0x55aa
+                && oem_cfg->head.content_len == content_len  && oem_cfg->tail.content_len == content_len
+                && oem_cfg->head.valid_flag == 1 && oem_cfg->tail.valid_flag == 1)
+        {
+            len = sizeof (oem_nv_cfg_version);
+            memcpy(tmp_buffer+pos, oem_nv_cfg_version, len);
+            pos += len;
+
+            len = sizeof (lynq_nv_cfg_bitmap);
+            memcpy(tmp_buffer+pos, lynq_nv_cfg_bitmap, len);
+            pos += len;
+
+            len = sizeof (oem_nv_cfg_bitmap);
+            memcpy(tmp_buffer+pos, oem_nv_cfg_bitmap, len);
+            pos += len;
+
+            for(x=0; x < sizeof(lynq_nv_cfg_bitmap); x++)
+            {
+                oem_cfg->content[x] &= oem_nv_cfg_bitmap[x];
+                oem_cfg->content[x] |= (lynq_cfg->content[x] & (~lynq_nv_cfg_bitmap[x]));
+            }
+
+            memcpy(puiArrPubKey, oem_nv_cfg_publickey, RSA_BYTE_LEN);
+            memcpy((puiArrPubKey+(RSA_U32_LEN*2 -1)), oem_nv_cfg_publickey + RSA_BYTE_LEN, sizeof(u32));
+            sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;
+            sRSAInput.udNbitLen = RAS_BIT_LEN;
+            sRSAInput.udEbitLen = RAS_BIT_LEN;
+            sRSAInput.pudInputM = (u32*)oem_nv_cfg_sign;
+            sRSAInput.pudInputE = (u32*)puiArrPubKey + RSA_U32_LEN;
+            sRSAInput.pudInputN = ((u32*)puiArrPubKey);
+            sRSAInput.pudOutputP = uiRsaResArr;
+
+            lynq_hex_display(sRSAInput.pudInputE, RSA_U32_LEN);
+            lynq_hex_display(sRSAInput.pudInputN, RSA_U32_LEN);
+            lynq_hex_display(sRSAInput.pudInputM, RSA_U32_LEN);
+
+            uiRet = Rsa_Calculate(sRSAInput);
+            if(uiRet != 0)
+            {
+                LYNQ_ERROR("oem calc rsa fail\n");
+                goto fail_exit;
+            }
+
+            lynq_hex_display(uiRsaResArr, RSA_U32_LEN);
+
+            uiRet = Hash_Calculate(HASH_MODE_MD5,
+                                   HASH_SMALL_ENDIAN,
+                                   (u32*)tmp_buffer,
+                                   pos,
+                                   NULL,
+                                   0,
+                                   uiHashResArr,
+                                   &uiHashResLen);
+            if(uiRet != 0)
+            {
+                LYNQ_ERROR("oem calc hash fail\n");
+                goto fail_exit;
+            }
+            lynq_hex_display(uiHashResArr, uiHashResLen);
+
+            puiRsaResAddr = sRSAInput.pudOutputP + (RSA_U32_LEN - uiHashResLen);
+
+            if (memcmp(puiRsaResAddr, uiHashResArr, uiHashResLen*sizeof (u32)) != 0)
+            {
+                LYNQ_ERROR("not valid oem sign\n");
+                goto fail_exit;
+            }
+        }
+        else
+        {
+            LYNQ_ERROR("not valid oem head\n");
+            goto fail_exit;
+        }
+    }
+    else
+    {
+        LYNQ_ERROR("not valid oem cfg\n");
+        goto fail_exit;
+    }
+
+    return tmp_buffer;
+fail_exit:
+    free(tmp_buffer);
+    return NULL;
+}
+
+#endif
+
diff --git a/boot/common/src/uboot/drivers/peripheral/oem_nv_cfg.h b/boot/common/src/uboot/drivers/peripheral/oem_nv_cfg.h
new file mode 100755
index 0000000..82d0a91
--- /dev/null
+++ b/boot/common/src/uboot/drivers/peripheral/oem_nv_cfg.h
@@ -0,0 +1,32 @@
+#ifndef __OEM_NV_CFG__H__
+#define __OEM_NV_CFG__H__
+
+static const char oem_nv_cfg_version[] = "oem_20240617";
+static const char oem_nv_cfg_value[] = {
+    '\x55', '\xaa', '\x19', '\x00', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39', '\x30', '\x31', '\x32',
+    '\xaa', '\x55', '\x19', '\x00', '\x10', '\x00', '\x00', '\x00'
+};
+
+static const char oem_nv_cfg_publickey[] = {
+    '\x85', '\xb2', '\x39', '\x98', '\x5d', '\x46', '\xb4', '\xc0', '\x7d', '\x30', '\x47', '\x7e', '\xa8', '\x1a', '\x8c', '\xdf',
+    '\x2c', '\x02', '\xdf', '\xb0', '\xeb', '\x95', '\x2b', '\xf0', '\xde', '\x04', '\xe8', '\xcd', '\x4c', '\x94', '\x49', '\x2d',
+    '\xe8', '\xa0', '\xcc', '\x91', '\x6e', '\xb3', '\xba', '\x53', '\x31', '\x21', '\x88', '\xbf', '\xd8', '\x7f', '\xab', '\x24',
+    '\xd4', '\x07', '\x76', '\xb6', '\x23', '\x6c', '\x43', '\x9e', '\x15', '\x4c', '\xc2', '\x67', '\x49', '\x47', '\x02', '\x8b',
+    '\x19', '\x52', '\x29', '\xd2', '\xd7', '\xdb', '\x7e', '\x48', '\xa3', '\x53', '\x03', '\xb9', '\xd6', '\x10', '\xb8', '\x52',
+    '\x18', '\x92', '\xf0', '\x4d', '\x96', '\x62', '\xc0', '\x65', '\x17', '\x51', '\xc0', '\x4c', '\xa1', '\x5c', '\x92', '\xeb',
+    '\x83', '\xc5', '\x61', '\xbe', '\x85', '\x1f', '\x21', '\x16', '\xf1', '\xbc', '\x17', '\xa0', '\xfe', '\x15', '\x03', '\xcf',
+    '\x82', '\x2b', '\xd6', '\x7e', '\x82', '\xdb', '\xfc', '\xd5', '\xe3', '\xc5', '\x9d', '\x73', '\x5d', '\xb1', '\x51', '\xbf',
+    '\x01', '\x00', '\x01', '\x00'
+};
+static const char oem_nv_cfg_sign[] = {
+    '\xc8', '\x48', '\x27', '\x16','\x8e', '\x43', '\x5d', '\xb2', '\x00', '\xac', '\x49', '\x8f','\x0c', '\xef', '\xf0', '\xdb',
+    '\x7d', '\x5c', '\xa9', '\x30','\xe3', '\x7e', '\xbe', '\xbd', '\xe9', '\xa4', '\x20', '\x9f','\x49', '\x65', '\xed', '\x3e',
+    '\x63', '\xfa', '\xeb', '\xbf','\xb9', '\xa6', '\x7f', '\x7e', '\x6e', '\x65', '\xfb', '\x84','\xf5', '\x6b', '\xc8', '\xe0',
+    '\x62', '\x3a', '\x55', '\xc9','\xa9', '\xc1', '\x64', '\x3a', '\xdf', '\x2e', '\xc6', '\xf2','\x5d', '\xcc', '\xa5', '\x28',
+    '\xfd', '\xaa', '\x33', '\x55','\x41', '\x8d', '\x26', '\xc8', '\x8a', '\xba', '\x73', '\x57','\x5c', '\xd5', '\x54', '\xbd',
+    '\x22', '\x7f', '\xcd', '\x04','\x28', '\x1d', '\x94', '\xdf', '\x40', '\x17', '\x89', '\x53','\xf2', '\xef', '\x6c', '\x22',
+    '\x19', '\x49', '\xd8', '\xbd','\xb4', '\xf7', '\x8f', '\x08', '\xd2', '\x08', '\x76', '\xa2','\xc8', '\xc3', '\x96', '\xc4',
+    '\x6d', '\x60', '\x10', '\x3f','\xb6', '\x87', '\x63', '\xec', '\x82', '\x81', '\x19', '\x63','\xac', '\x42', '\xf4', '\xc6'
+};
+
+#endif
diff --git a/boot/common/src/uboot/drivers/peripheral/peripheral.c b/boot/common/src/uboot/drivers/peripheral/peripheral.c
index fe410a9..3898062 100755
--- a/boot/common/src/uboot/drivers/peripheral/peripheral.c
+++ b/boot/common/src/uboot/drivers/peripheral/peripheral.c
@@ -28,6 +28,11 @@
 #include <drvs_gpio.h>

 #include "common.h"

 #include <dma_cfg.h>

+#include "../rsa/drv_rsa.h"

+

+#ifdef LYNQ_NV_CFG_SUPPORT

+extern void lynq_setup_nv_cfg(void);

+#endif

 

 //#include <gpio.h>

 

@@ -67,9 +72,16 @@
 	int ret = 0;

 	ret = power_init();

 	

+	BOOT_PRINTF(UBOOT_NOTICE, "cy: peripheral_init 2\n");

+

+#ifndef LYNQ_NV_CFG_SUPPORT

 /*mmc config*/

-	REG32(MMC_FLAG_ADDR) &=~0x3;//clear bit0~1	

+   	REG32(MMC_FLAG_ADDR) &=~0x3;//clear bit0~1	

 	REG32(MMC_FLAG_ADDR) |=((MMC0_USED_EN<<0)|(MMC1_USED_EN<<1));

+#else

+	lynq_setup_nv_cfg();

+#endif

+

 /*led*/

 /*lcd*/

 

diff --git a/pub/project/zx297520v3/include/drv/dma_cfg.h b/pub/project/zx297520v3/include/drv/dma_cfg.h
index b83ca2b..5cd218e 100755
--- a/pub/project/zx297520v3/include/drv/dma_cfg.h
+++ b/pub/project/zx297520v3/include/drv/dma_cfg.h
@@ -204,11 +204,24 @@
 #define EXCEPT_FLAG_ADDR         (BOOT_FLAG_ADDR + BOOT_FLAG_SIZE)

 #define EXCEPT_FLAG_SIZE         (0x4UL)

 

+//youchen@2024-06-20 add for lynq nv config begin

+#define LYNQ_NV_CFG_SUPPORT 1

+

+#ifndef LYNQ_NV_CFG_SUPPORT

+

 #define MMC_FLAG_ADDR         (EXCEPT_FLAG_ADDR + EXCEPT_FLAG_SIZE)

 #define MMC_FLAG_SIZE         (0x4UL)/*bit 0: mmc0 exit,bit1 mmc1 exit*/

-

 #define RAM_CONFIG_END (MMC_FLAG_ADDR+MMC_FLAG_SIZE)

 

+#else

+

+#define MMC_LYNQ_NV_CFG_ADDR         (EXCEPT_FLAG_ADDR + EXCEPT_FLAG_SIZE)

+#define MMC_LYNQ_NV_CFG_SIZE         (0x100UL)

+#define RAM_CONFIG_END (MMC_LYNQ_NV_CFG_ADDR+MMC_LYNQ_NV_CFG_SIZE)

+

+#endif 

+//youchen@2024-06-20 add for lynq nv config end

+

 //#if RAM_CONFIG_END > (IRAM_BASE_ADDR_DRV+IRAM_BASE_LEN_DRV)

 //#error error drv_ram_cfg !!!!!!!!!!!!!!!

 //#endif