[Feature][R306-MTN][task-view-1032] add wifi, phy, leds and Button

Change-Id: I2358bc67d30e0e34f7dacf021426e40eb70d9c24
diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/gpio_cfg.h b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/gpio_cfg.h
index b6c7404..4aa9c88 100644
--- a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/gpio_cfg.h
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/gpio_cfg.h
@@ -162,23 +162,25 @@
 #define LED_4G_4_FUNC_SEL		GPIO74_GPIO74

 #define LED_4G_5_FUNC_SEL		GPIO75_GPIO75

 

-#elif defined(CONFIG_ARCH_ZX297520V3_MIFI)

-#ifdef CONFIG_MIN_VERSION

-#define PIN_LED_MODEM_RED 		ZX29_GPIO_124

-#define PIN_LED_MODEM_GREEN 	ZX29_GPIO_125

-//#define PIN_LED_MODEM_BLUE 		ZX29_GPIO_123

-#define PIN_LED_SMS 			ZX29_GPIO_40

-#define PIN_LED_WIFI 		 	ZX29_GPIO_39

-#define PIN_LED_BATTARY_RED 	ZX29_GPIO_41

-#define PIN_LED_BATTARY_GREEN 	ZX29_GPIO_42

+#elif defined(CONFIG_ARCH_ZX297520V3_CPE)

+#if 1 //CONFIG_MIN_VERSION

+#define PIN_LED_MODEM_RED 		ZX29_GPIO_75

+#define PIN_LED_MODEM_GREEN 	ZX29_GPIO_73

+#define PIN_LED_MODEM_BLUE 		ZX29_GPIO_74

+//#define PIN_LED_SMS 			ZX29_GPIO_40

+#define PIN_LED_WIFI 		 	ZX29_GPIO_76

+#define PIN_LED_ETH 		 	ZX29_GPIO_77

+#define PIN_LED_BATTARY_RED 	ZX29_GPIO_46

+#define PIN_LED_BATTARY_GREEN 	ZX29_GPIO_72

 

-#define LED_MODEM_RED_FUNC_SEL 		GPIO124_GPIO124

-#define LED_MODEM_GREEN_FUNC_SEL 	GPIO125_GPIO125

-//#define LED_MODEM_BLUE_FUNC_SEL 	GPIO123_GPIO123

-#define LED_SMS_FUNC_SEL 			GPIO40_GPIO40

-#define LED_WIFI_FUNC_SEL 			GPIO39_GPIO39

-#define LED_BATTARY_RED_FUNC_SEL 	GPIO41_GPIO41

-#define LED_BATTARY_GREEN_SEL 		GPIO42_GPIO42

+#define LED_MODEM_RED_FUNC_SEL 		GPIO75_GPIO75

+#define LED_MODEM_GREEN_FUNC_SEL 	GPIO73_GPIO73

+#define LED_MODEM_BLUE_FUNC_SEL 	GPIO74_GPIO74

+//#define LED_SMS_FUNC_SEL 			GPIO40_GPIO40

+#define LED_WIFI_FUNC_SEL 			GPIO76_GPIO76

+#define LED_ETH_FUNC_SEL 			GPIO77_GPIO77

+#define LED_BATTARY_RED_FUNC_SEL 	GPIO46_GPIO46

+#define LED_BATTARY_GREEN_SEL 		GPIO72_GPIO72

 #else

 #define PIN_LED_MODEM_RED 		ZX29_GPIO_124

 //#define PIN_LED_MODEM_GREEN 	ZX29_GPIO_44

@@ -303,8 +305,8 @@
 #define PIN_WIFI_PWR_BUCK_GPIO_SEL		GPIO77_GPIO77

 

 //WIFI power control pin, EVB is 27.

-#define PIN_WIFI_PWR_CTL					ZX29_GPIO_121

-#define PIN_WIFI_PWR_CTL_SEL				GPIO121_GPIO121

+#define PIN_WIFI_PWR_CTL					ZX29_GPIO_91

+#define PIN_WIFI_PWR_CTL_SEL				GPIO91_GPIO91

 

 //WIFI chip enable pin.

 #ifdef CONFIG_ARCH_ZX297520V3_MIFI

@@ -314,8 +316,8 @@
 #define PIN_WIFI_CHIP_ENABLE				ZX29_GPIO_85

 #define PIN_WIFI_CHIP_ENABLE_SEL			GPIO85_GPIO85

 #elif defined (CONFIG_ARCH_ZX297520V3_CPE)

-#define PIN_WIFI_CHIP_ENABLE				ZX29_GPIO_120

-#define PIN_WIFI_CHIP_ENABLE_SEL			GPIO120_GPIO120

+#define PIN_WIFI_CHIP_ENABLE				ZX29_GPIO_132

+#define PIN_WIFI_CHIP_ENABLE_SEL			GPIO132_GPIO132

 #elif defined (CONFIG_ARCH_ZX297520V3_CPE_SWITCH)

 #define PIN_WIFI_CHIP_ENABLE				ZX29_GPIO_123

 #define PIN_WIFI_CHIP_ENABLE_SEL			GPIO123_GPIO123

diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-cpe-devices.c b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-cpe-devices.c
new file mode 100755
index 0000000..100935c
--- /dev/null
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-cpe-devices.c
@@ -0,0 +1,1619 @@
+/*
+ * arch/arm/mach-zx297520v3/zx297520v3_devices.c
+ *
+ *  Copyright (C) 2015 ZTE-TSP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/soc/zte/rpm/rpmsg.h>
+#include <linux/i2c.h>
+
+#include <mach/dma.h>
+#include <mach/board.h>
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+#include <mach/i2c.h>
+#include <mach/gpio.h>
+#include <mach/zx29_mmc.h>
+#include <mach/zx29_uart_def.h>
+#include <linux/soc/zte/tsc/tsc.h>
+
+#if (defined CONFIG_SPI_ZX29) || (defined CONFIG_SPI_GPIO)
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <mach/spi.h>
+#include <linux/video/zx29_lcd.h>
+#endif
+
+#ifdef CONFIG_CHARGER_ZX234502
+#include <linux/power/zx234502_charger.h>
+#endif
+#ifdef CONFIG_CHARGER_AW3215
+#include <linux/power/aw3215_charger.h>
+#endif
+#ifdef CONFIG_LEDS_GPIO
+#include <linux/leds.h>
+#endif
+#ifdef CONFIG_MMC_ZX29
+#include <linux/mmc/host.h>
+#endif
+#ifdef CONFIG_KEYBOARD_ZX_INT
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#endif
+#ifdef CONFIG_KEYBOARD_ZX_5x6
+#include <linux/input.h>
+#include <linux/input/zx29_keypad_5x6.h>
+#endif
+#ifdef CONFIG_ZX29_GMAC
+#include <linux/gmac/gmac.h>
+#endif
+#ifdef CONFIG_MFD_ZX234290_I2C
+#include <linux/mfd/zx234290.h>
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_FT6X06
+#include <linux/input/ft6x06_ts.h>
+#endif
+
+#if (defined CONFIG_SND_SOC_ZX297520V3) || (defined CONFIG_SND_SOC_ZX297520V3_MODULE)
+#include <sound/zx29_snd_platform.h>
+#endif
+#include <mach/gpio_cfg.h>
+
+
+struct zx29_uart_platdata  zx29_uart0_platdata= {
+		.uart_use = 1,
+		.uart_rxd.gpioname = "uart0_rxd",
+		.uart_rxd.gpionum = PIN_UART0_RXD,
+		.uart_rxd.gpiofnc = FNC_UART0_RXD,
+		.uart_txd.gpioname = "uart0_txd",
+		.uart_txd.gpionum = PIN_UART0_TXD,
+		.uart_txd.gpiofnc = FNC_UART0_TXD,
+		.uart_ctsrtsuse = 0,
+#ifndef CONFIG_ARCH_ZX297520V3_CPE		
+		.uart_cts.gpioname = "uart0_cts",
+		.uart_cts.gpionum= PIN_UART0_CTS ,
+		.uart_cts.gpiofnc = FNC_UART0_CTS ,
+		.uart_rts.gpioname = "uart0_rts",
+		.uart_rts.gpionum =PIN_UART0_RTS,
+		.uart_rts.gpiofnc = FNC_UART0_RTS,
+#endif		
+		.uart_abauduse = 0,
+		.uart_input_enable = 1,
+		.uart_wakeup_enable = 1,
+};
+struct zx29_uart_platdata  zx29_uart1_platdata= {
+		.uart_use = 1,
+#ifndef CONFIG_ARCH_ZX297520V3_CPE
+		.uart_rxd.gpioname = "uart1_rxd",
+		.uart_rxd.gpionum = PIN_UART1_RXD,
+		.uart_rxd.gpiofnc = FNC_UART1_RXD,
+		.uart_txd.gpioname = "uart1_txd",
+		.uart_txd.gpionum = PIN_UART1_TXD,
+		.uart_txd.gpiofnc = FNC_UART1_TXD,
+		.uart_ctsrtsuse = 0,
+		.uart_cts.gpioname = "uart1_cts",
+		.uart_cts.gpionum= PIN_UART1_CTS ,
+		.uart_cts.gpiofnc = FNC_UART1_CTS ,
+		.uart_rts.gpioname = "uart1_rts",
+		.uart_rts.gpionum = PIN_UART1_RTS,
+		.uart_rts.gpiofnc = FNC_UART1_RTS,
+#else
+		.uart_rxd.gpioname = "uart0_rts",
+		.uart_rxd.gpionum = PIN_UART0_RTS,
+		.uart_rxd.gpiofnc = GPIO32_UART1_RXD,
+		.uart_txd.gpioname = "uart0_cts",
+		.uart_txd.gpionum = PIN_UART0_CTS,
+		.uart_txd.gpiofnc = GPIO31_UART1_TXD,
+		.uart_ctsrtsuse = 0,
+#if 0		
+		.uart_cts.gpioname = "uart1_cts",
+		.uart_cts.gpionum= PIN_UART1_CTS ,
+		.uart_cts.gpiofnc = FNC_UART1_CTS ,
+		.uart_rts.gpioname = "uart1_rts",
+		.uart_rts.gpionum = PIN_UART1_RTS,
+		.uart_rts.gpiofnc = FNC_UART1_RTS,
+#endif	
+#endif
+
+		.uart_abauduse = 0,
+		.uart_input_enable = 1,
+};
+struct zx29_uart_platdata  zx29_uart2_platdata= {
+		.uart_use = 0,
+		.uart_rxd.gpioname = "uart2_rxd",
+		.uart_rxd.gpionum = PIN_UART2_RXD,
+		.uart_rxd.gpiofnc = FNC_UART2_RXD,
+		.uart_txd.gpioname = "uart2_txd",
+		.uart_txd.gpionum = PIN_UART2_TXD,
+		.uart_txd.gpiofnc = FNC_UART2_TXD,
+		.uart_ctsrtsuse = 0,
+		.uart_cts.gpioname = "uart2_cts",
+		.uart_cts.gpionum= PIN_UART2_CTS ,
+		.uart_cts.gpiofnc = FNC_UART2_CTS ,
+		.uart_rts.gpioname = "uart2_rts",
+		.uart_rts.gpionum = PIN_UART2_RTS,
+		.uart_rts.gpiofnc = FNC_UART2_RTS,
+		.uart_abauduse = 0,
+		.uart_input_enable = 1,
+};
+/* --------------------------------------------------------------------
+ *  UART
+ * -------------------------------------------------------------------- */
+#ifdef CONFIG_SERIAL_ZX29_UART
+/* UART0*/
+static struct resource zx29_uart0_resources[] = {
+	[0] = {
+		.start	= ZX29_UART0_PHYS,
+		.end	= ZX29_UART0_PHYS + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= UART0_MIX_INT,
+		.end	= UART0_MIX_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.name    =   "zx29_uart_rxd_wakeup",
+		.start	= UART0_RXD_INT,
+		.end	= UART0_RXD_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device zx29_uart0_device = {
+	.name		= "zx29_uart",
+	.id		= 0,
+	.resource	= zx29_uart0_resources,
+	.num_resources	= ARRAY_SIZE(zx29_uart0_resources),
+	.dev = {
+		.platform_data = &zx29_uart0_platdata,
+	}
+};
+/* UART2*/
+static struct resource zx29_uart1_resources[] = {
+	[0] = {
+		.start	= ZX29_UART1_PHYS,
+		.end	= ZX29_UART1_PHYS + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= UART1_MIX_INT,
+		.end	= UART1_MIX_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device zx29_uart1_device = {
+	.name		= "zx29_uart",
+	.id		= 1,
+	.resource	= zx29_uart1_resources,
+	.num_resources	= ARRAY_SIZE(zx29_uart1_resources),
+	.dev = {
+		.platform_data = &zx29_uart1_platdata,
+	}
+};
+
+/* UART2*/
+static struct resource zx29_uart2_resources[] = {
+	[0] = {
+		.start	= ZX29_UART2_PHYS,
+		.end	= ZX29_UART2_PHYS + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= UART2_MIX_INT,
+		.end	= UART2_MIX_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device zx29_uart2_device = {
+	.name		= "zx29_uart",
+	.id		= 2,
+	.resource	= zx29_uart2_resources,
+	.num_resources	= ARRAY_SIZE(zx29_uart2_resources),
+	.dev = {
+		.platform_data = & zx29_uart2_platdata,
+	}
+};
+#endif
+
+/* --------------------------------------------------------------------
+ *	DMA -- Direct Memory Access
+* -------------------------------------------------------------------- */
+#ifdef CONFIG_ZX29_DMA
+static struct resource zx29_dma_res[] = {
+	[0] = {
+		.start	= (u32)ZX_DMA_PS_BASE,
+		.end	= (u32)ZX_DMA_PS_BASE + SZ_4K - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = PS_DMA_INT,
+		.end   = PS_DMA_INT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+static struct platform_device zx29_dma_device = {
+	.name = "zx29_dma",
+	.id = 0,
+	.resource = zx29_dma_res,
+	.num_resources	= ARRAY_SIZE(zx29_dma_res),
+};
+#endif
+
+#if (defined CONFIG_SND_SOC_ZX297520V3) || (defined CONFIG_SND_SOC_ZX297520V3_MODULE)
+
+static struct platform_device zx29_audio = {
+	.name		= SND_MACHINE_PDEV_NAME,
+	.id		= -1,
+	.dev		= {
+		.platform_data	= ZX29_SND_MACH_PDATA, //&snd_machine_pdata,
+	},
+};
+#endif
+
+#if (defined CONFIG_SND_SOC_ZX_PCM) || (defined CONFIG_SND_SOC_ZX_PCM_MODULE)
+/* ASOC DMA */
+static unsigned long long zx29_device_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device zx29_asoc_dma = {
+	.name		= "zx29-pcm-audio",
+	.id		= -1,
+	.dev		= {
+		.dma_mask		= &zx29_device_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	}
+};
+#endif
+
+/* --------------------------------------------------------------------
+ *	I2S
+* -------------------------------------------------------------------- */
+//#ifdef CONFIG_SND_SOC_ZX_I2S
+#if (defined CONFIG_SND_SOC_ZX_I2S) || (defined CONFIG_SND_SOC_ZX_I2S_MODULE)
+#define zx29_I2S0	1
+//#define zx29_I2S1	1
+
+#ifdef zx29_I2S0
+/* I2S0 */
+static struct resource i2s0_res[] = {
+	[0] = {
+		.start	= (u32)ZX_I2S0_BASE,
+		.end	= (u32)ZX_I2S0_BASE + SZ_4K - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMA_CH_I2S0_TX,
+		.end   = DMA_CH_I2S0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMA_CH_I2S0_RX0,
+		.end   = DMA_CH_I2S0_RX0,
+		.flags = IORESOURCE_DMA,
+	},
+};
+static struct platform_device zx29_i2s0_device = {
+	.name = "zx29_i2s",
+	.id = 0,
+	.resource = i2s0_res,
+	.num_resources	= ARRAY_SIZE(i2s0_res),
+};
+#endif
+
+#ifdef zx29_I2S1
+static struct resource i2s1_res[] = {
+	[0] = {
+		.start	= (u32)ZX_I2S1_BASE,
+		.end	= (u32)ZX_I2S1_BASE + SZ_4K - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMA_CH_I2S1_TX,
+		.end   = DMA_CH_I2S1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMA_CH_I2S1_RX0,
+		.end   = DMA_CH_I2S1_RX0,
+		.flags = IORESOURCE_DMA,
+	},
+};
+static struct platform_device zx29_i2s1_device = {
+	.name = "zx29_i2s",
+	.id = 1,
+	.resource = i2s1_res,
+	.num_resources	= ARRAY_SIZE(i2s1_res),
+};
+#endif
+#endif
+
+#if (defined CONFIG_SND_SOC_ZX_VOICE) || (defined CONFIG_SND_SOC_ZX_VOICE_MODULE)
+static struct platform_device voice_asoc_device = {
+	.name = "voice_audio",
+	.id = -1,
+};
+#endif
+/* --------------------------------------------------------------------
+ *  MMC / SD
+ * -------------------------------------------------------------------- */
+#ifdef CONFIG_MMC_ZX29
+static struct resource zx29_sdmmc0_resources[] = {
+	[0] = {
+		.start	= ZX_SD0_BASE,
+		.end	= ZX_SD0_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= SD0_INT,
+		.end	= SD0_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct dw_mci_board zx29_sdmmc0_platdata = {
+	.num_slots	= 1,
+#if 1//def CONFIG_RTL8192CD
+	.quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION | DW_MCI_QUIRK_SDIO \
+	| DW_MCI_QUIRK_UNALIGN_DMA_SZ | DW_MCI_QUIRK_UNALIGN_DMA_START |DW_MCI_QUIRK_CLK_PHASE_TURN ,
+	.caps	= (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |MMC_CAP_UHS_SDR50 | MMC_CAP_SDIO_IRQ |MMC_CAP_NONREMOVABLE),
+#else
+	.quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION | DW_MCI_QUIRK_SDIO,
+	.caps	= (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |MMC_CAP_UHS_SDR50),
+#endif
+	.bus_hz = 100*1000*1000,
+	.pm_caps = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY,
+	.data1_irq = SD0_DATA1_INT,
+};
+static struct platform_device zx29_sdmmc0_device = {
+	.name		= "zx29_sd",
+	.id		= 0,
+	.resource	= zx29_sdmmc0_resources,
+	.num_resources	= ARRAY_SIZE(zx29_sdmmc0_resources),
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data		= &zx29_sdmmc0_platdata,
+	},
+};
+static struct resource zx29_sdmmc1_resources[] = {
+	[0] = {
+		.start	= ZX_SD1_BASE,
+		.end	= ZX_SD1_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= SD1_INT,
+		.end	= SD1_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct dw_mci_board zx29_sdmmc1_platdata = {
+	.num_slots	= 1,
+	.quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
+	.bus_hz = 50*1000*1000,
+	.caps	= (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_NONREMOVABLE),
+	.pm_caps = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY,
+	//.init = sdmmc_init,
+	//.setpower = sdmmc_set_power,
+
+	.detect_delay_ms = 500,
+};
+static struct platform_device zx29_sdmmc1_device = {
+	.name		= "zx29_sd",
+	.id		= 1,
+	.resource	= zx29_sdmmc1_resources,
+	.num_resources	= ARRAY_SIZE(zx29_sdmmc1_resources),
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data		= &zx29_sdmmc1_platdata,
+	},
+};
+#endif
+
+/* --------------------------------------------------------------------
+ *  NAND
+ * -------------------------------------------------------------------- */
+#ifdef CONFIG_MTD_ZXIC_SPIFC
+ static struct resource spi_nand_resource[] = {
+	  [0] = {
+		  .start  = ZX_SPIFC0_BASE,
+		  .end	  = ZX_SPIFC0_BASE + SZ_4K - 1,
+		  .flags  = IORESOURCE_MEM,
+		  .name   = "spifc_reg",
+	  },
+	  [2] = {
+		  .start  = SPI_FC0_INT,
+		  .end	  = SPI_FC0_INT,
+		  .flags  = IORESOURCE_IRQ,
+
+	  },
+  };
+#endif
+#ifdef CONFIG_MTD_NAND_DENALI
+static struct resource denali_nand_resource[] = {
+	[0] = {
+		.start	= ZX_NAND_REG_BASE,
+		.end	= ZX_NAND_REG_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+		.name   = "denali_reg",
+	},
+	[1] = {
+		.start	= ZX_NAND_DATA_BASE,
+		.end	= ZX_NAND_DATA_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+		.name   = "nand_data",
+	},
+    [2] = {
+		.start	= NAND_INT,
+		.end	= NAND_INT,
+		.flags	= IORESOURCE_IRQ,
+
+	},
+};
+struct denali_nand_data {
+	struct mtd_partition *parts;
+	int (*dev_ready)(struct mtd_info *mtd);
+	u32 nr_parts;
+	u8 ale;		/* address line number connected to ALE */
+	u8 cle;		/* address line number connected to CLE */
+	u8 width;	/* buswidth */
+	u8 chip_delay;
+};
+static struct denali_nand_data zx29_nand_data = {
+	.cle		= 0,
+	.ale		= 1,
+	.width		= 8,
+};
+struct platform_device zx29_device_nand = {
+	.name		= "denali-nand-dt",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &zx29_nand_data,
+	},
+	.num_resources	= ARRAY_SIZE(denali_nand_resource),
+	.resource	= denali_nand_resource,
+};
+#endif
+
+#ifdef CONFIG_MTD_ZXIC_SPIFC
+struct platform_device zx29_device_spi_nand = {
+	.name		= "spi-nand-dt",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(spi_nand_resource),
+	.resource	= spi_nand_resource,
+};
+#endif
+
+/*
+ *--------------------------------------------------------------------
+ *  						NOR
+ * --------------------------------------------------------------------
+ */
+
+#ifdef CONFIG_SPI_ZXIC_NOR
+ static struct resource spi_nor_resource[] = {
+	  [0] = {
+		  .start  = ZX_SPIFC0_BASE,
+		  .end	  = ZX_SPIFC0_BASE + SZ_4K - 1,
+		  .flags  = IORESOURCE_MEM,
+		  .name   = "spi_nor_reg",
+	  },
+	  [2] = {
+		  .start  = SPI_FC0_INT,
+		  .end	  = SPI_FC0_INT,
+		  .flags  = IORESOURCE_IRQ,
+
+	  },
+  };
+
+struct platform_device zx29_device_spi_nor = {
+	.name		= "spi-nor-dt",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(spi_nor_resource),
+	.resource	= spi_nor_resource,
+};
+#endif
+
+
+
+/* --------------------------------------------------------------------
+ *  I2C
+ * -------------------------------------------------------------------- */
+#ifdef CONFIG_I2C_ZX29
+
+#define zx29_pmic_i2c	1
+#define zx29_I2C0		1
+
+
+#ifdef zx29_pmic_i2c
+static struct zx29_i2c_platform_data zx29_pmic_i2c_platform_data = {
+	.bus_clk_rate   = 300000,
+};
+
+static struct resource pmic_i2c_resources[] = {
+	[0] = {
+		.start	= (u32)ZX_PMIC_I2C_BASE,
+		.end	= (u32)ZX_PMIC_I2C_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= I2C0_INT,
+		.end	= I2C0_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device zx29_pmic_i2c_device = {
+	.name		= "zx29_i2c",
+	.id 	    = 0,
+	.resource	= pmic_i2c_resources,
+	.num_resources	= ARRAY_SIZE(pmic_i2c_resources),
+	.dev = {
+		.platform_data = &zx29_pmic_i2c_platform_data,
+	},
+};
+#endif
+
+#ifdef zx29_I2C0
+static struct zx29_i2c_platform_data zx29_i2c0_platform_data = {
+	.bus_clk_rate	 = 300000,
+};
+
+static struct resource i2c0_resources[] = {
+	[0] = {
+		.start	= (u32)ZX_I2C1_BASE,
+		.end	= (u32)ZX_I2C1_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= I2C1_INT,
+		.end	= I2C1_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device zx29_i2c0_device = {
+	.name		= "zx29_i2c",
+	.id 	    = 1,
+	.resource	= i2c0_resources,
+	.num_resources	= ARRAY_SIZE(i2c0_resources),
+	.dev = {
+		.platform_data = &zx29_i2c0_platform_data,
+	},
+};
+#endif
+
+
+#endif //end CONFIG_I2C_ZX29
+
+/* --------------------------------------------------------------------
+ *  SPI
+ * -------------------------------------------------------------------- */
+#ifdef CONFIG_SPI_ZX29
+static struct resource spi0_resources[] = {
+	[0]={
+		.start	= ZX_SSP0_BASE,
+		.end	= ZX_SSP0_BASE + SZ_32 - 1,
+		.name	= "registers",
+		.flags	= IORESOURCE_MEM,
+	},
+	[1]={
+		.start	= SSP0_INT,
+		.end	= SSP0_INT,
+		.name	= "interrupt",
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct zx29_spi_controller spi0_data ={
+	.bus_id = 0,
+	.num_chipselect = 1,
+	.enable_dma = 1,
+	.autosuspend_delay=0,
+	.dma_tx_param = (void*) DMA_CH_SSP0_TX,
+	.dma_rx_param = (void*) DMA_CH_SSP0_RX,
+};
+
+static struct platform_device zx29_ssp0_device = {
+	.name		= "zx29_ssp",
+	.id 	= 0,
+	.dev	={
+			.platform_data = &spi0_data,
+		},
+	.resource	= spi0_resources,
+	.num_resources	= ARRAY_SIZE(spi0_resources),
+};
+
+static struct resource spi1_resources[] = {
+	[0]={
+		.start	= ZX_SSP1_BASE,
+		.end	= ZX_SSP1_BASE + SZ_32 - 1,
+		.name	= "registers",
+		.flags	= IORESOURCE_MEM,
+	},
+	[1]={
+		.start	= SSP1_INT,
+		.end	= SSP1_INT,
+		.name	= "interrupt",
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct zx29_spi_controller spi1_data ={
+	.bus_id = 1,
+	.num_chipselect = 1,
+	.enable_dma = 1,
+	.autosuspend_delay=0,
+	.dma_tx_param = (void*) DMA_CH_SSP1_TX,
+	.dma_rx_param = (void*) DMA_CH_SSP1_RX,
+};
+
+static struct platform_device zx29_ssp1_device = {
+	.name		= "zx29_ssp",
+	.id 	= 1,
+	.dev	={
+			.platform_data = &spi1_data,
+		},
+	.resource	= spi1_resources,
+	.num_resources	= ARRAY_SIZE(spi1_resources),
+};
+#endif
+
+#ifdef CONFIG_SPI_GPIO
+static struct spi_gpio_platform_data zx29_spi_gpio_cfg0 = {
+    .sck        = 26,
+    .mosi       = 28,
+    .miso       = 27,
+	.num_chipselect = 1,
+	.sck_func = GPIO26_GPIO26,
+	.mosi_func = GPIO28_GPIO28,
+	.miso_func = GPIO27_GPIO27,
+};
+static struct platform_device zx29_spi_gpio_dev0 = {
+    .name       = "spi_gpio",
+    .id     = 0,
+    .dev.platform_data = &zx29_spi_gpio_cfg0,
+};
+
+static struct spi_gpio_platform_data zx29_spi_gpio_cfg1 = {
+    .sck        = 88,
+    .mosi       = 90,
+    .miso       = 89,
+	.num_chipselect = 1,
+	.sck_func = GPIO88_GPIO88,
+	.mosi_func = GPIO90_GPIO90,
+	.miso_func = GPIO89_GPIO89,
+};
+static struct platform_device zx29_spi_gpio_dev1 = {
+    .name       = "spi_gpio",
+    .id     = 1,
+    .dev.platform_data = &zx29_spi_gpio_cfg1,
+};
+#endif
+
+/* --------------------------------------------------------------------
+ *  USB
+ * -------------------------------------------------------------------- */
+#ifdef CONFIG_DWC_OTG_USB
+/* USB 20*/
+static struct resource zx29_usb0_resources[] = {
+	[0] = {
+		.start	= ZX29_USB_PHYS,
+		.end	= ZX29_USB_PHYS + SZ_256K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name   = "usb_int",
+		.start	= USB_INT,
+		.end	= USB_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+	 	 .name   = "usb_powerdown_up",
+		 .start  = USB_POWERDWN_UP_INT,
+		 .end	 = USB_POWERDWN_UP_INT,
+		 .flags  = IORESOURCE_IRQ,
+	},
+	[3] = {
+	 	 .name   = "usb_powerdown_down",
+		 .start  = USB_POWERDWN_DOWN_INT,
+		 .end	 = USB_POWERDWN_DOWN_INT,
+		 .flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device zx29_usb0_device = {
+	.name		= "zx29_hsotg",
+	.id		= 0,
+	.resource	= zx29_usb0_resources,
+	.num_resources	= ARRAY_SIZE(zx29_usb0_resources),
+};
+#endif
+
+#ifdef CONFIG_USB_DWC_OTG_HCD
+ /* HSIC*/
+static struct resource zx29_usb1_resources[] = {
+ [0] = {
+	 .start  = ZX29_HSIC_PHYS,
+	 .end	 = ZX29_HSIC_PHYS + SZ_256K - 1,
+	 .flags  = IORESOURCE_MEM,
+ },
+ [1] = {
+ 	 .name   = "hsic_int",
+	 .start  = HSIC_INT,
+	 .end	 = HSIC_INT,
+	 .flags  = IORESOURCE_IRQ,
+ },
+ [2] = {
+ 	 .name   = "hsic_powerdown_up",
+	 .start  = HSIC_POWERDWN_UP_INT,
+	 .end	 = HSIC_POWERDWN_UP_INT,
+	 .flags  = IORESOURCE_IRQ,
+ },
+ [3] = {
+ 	 .name   = "hsic_powerdown_down",
+	 .start  = HSIC_POWERDWN_DOWN_INT,
+	 .end	 = HSIC_POWERDWN_DOWN_INT,
+	 .flags  = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device zx29_usb1_device = {
+ .name		 = "zx29_hsic",
+ .id	 = 1,
+ .resource	 = zx29_usb1_resources,
+ .num_resources  = ARRAY_SIZE(zx29_usb1_resources),
+};
+#endif
+
+/* --------------------------------------------------------------------
+ * ICP
+ * -------------------------------------------------------------------- */
+#ifdef CONFIG_RPM_ZX29
+ /*ICP_M0/ICP_ARM0*/
+static struct zx29_rpmsg_platform_data rpmsg_m0_platform_data = {
+	.iram_send_base	= (u32)ICP_IRAM_APM0_BASEADDR,
+	.iram_send_size	= ICP_IRAM_APM0_SIZE,
+  	.iram_recv_base	= (u32)ICP_IRAM_M0AP_BASEADDR,
+	.iram_recv_size	= ICP_IRAM_M0AP_SIZE,
+  	.ddr_send_base	= (u32)ICP_DDR_APM0_BASEADDR,
+  	.ddr_send_size	= ICP_DDR_APM0_SIZE,
+  	.ddr_recv_base	= (u32)ICP_DDR_M0AP_BASEADDR,
+  	.ddr_recv_size	= ICP_DDR_M0AP_SIZE,
+  	.max_channel_cnt= CHANNEL_AP2M0_MAXID,
+};
+
+static struct resource icp_m0_resources[] = {
+	[0] = {
+		.start	= ICP_M02PS_INT,
+		.end	= ICP_M02PS_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[1] = {
+		.start	= (u32)ZX29_ICP_APM0_REG,
+		.end	= (u32)ZX29_ICP_APM0_REG + 0x30,
+		.flags	= IORESOURCE_MEM,
+		.name 	= "icp",
+	},
+
+};
+
+static struct zx29_rpmsg_platform_data rpmsg_ps_platform_data = {
+	.iram_send_base	= (u32)ICP_IRAM_APPS_BASEADDR,
+	.iram_send_size	= ICP_IRAM_APPS_SIZE,
+  	.iram_recv_base	= (u32)ICP_IRAM_PSAP_BASEADDR,
+	.iram_recv_size	= ICP_IRAM_PSAP_SIZE,
+  	.ddr_send_base	= (u32)ICP_DDR_APPS_BASEADDR,
+  	.ddr_send_size	= ICP_DDR_APPS_SIZE,
+  	.ddr_recv_base	= (u32)ICP_DDR_PSAP_BASEADDR,
+  	.ddr_recv_size	= ICP_DDR_PSAP_SIZE,
+  	.max_channel_cnt= CHANNEL_AP2PS_MAXID,
+};
+
+static struct resource icp_ps_resources[] = {
+	[0] = {
+		.start	= ICP_AP2PS_INT,
+		.end	= ICP_AP2PS_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[1] = {
+		.start	= (u32)ZX29_ICP_APPS_REG,
+		.end	= (u32)ZX29_ICP_APPS_REG + 0x30,
+		.flags	= IORESOURCE_MEM,
+		.name 	= "icp",
+	},
+};
+
+/* AP <--> m0 */
+static struct platform_device zx29_icp_m0_device = {
+	.name		= "icp",
+	.id			= 0,
+	.resource	= icp_m0_resources,
+	.num_resources	= ARRAY_SIZE(icp_m0_resources),
+	.dev = {
+		.platform_data = &rpmsg_m0_platform_data,
+	},
+};
+
+/* AP <--> ps */
+static struct platform_device zx29_icp_ps_device = {
+	.name		= "icp",
+	.id			= 1,
+	.resource	= icp_ps_resources,
+	.num_resources	= ARRAY_SIZE(icp_ps_resources),
+	.dev = {
+		.platform_data = &rpmsg_ps_platform_data,
+	},
+};
+#endif
+
+/* --------------------------------------------------------------------
+ *	WDT -- ap watchdog timer
+* -------------------------------------------------------------------- */
+#ifdef CONFIG_ZX29_WATCHDOG
+static struct resource wdt_res[] = {
+	[0] = {
+		.start	= (u32)ZX_AP_WDT_BASE,
+		.end	= (u32)ZX_AP_WDT_BASE + SZ_4K - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = WDT_INT,
+		.end   = WDT_INT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+static struct platform_device zx29_wdt_device = {
+	.name = "zx29_ap_wdt",
+	.id = 0,
+	.resource = wdt_res,
+	.num_resources	= ARRAY_SIZE(wdt_res),
+};
+#endif
+
+#ifdef CONFIG_LEDS_GPIO
+
+struct gpio_led leds[]={
+	{
+		.name = "modem_r_led",
+		.pin_select = 0,/*gpio*/
+		.gpio = PIN_LED_MODEM_RED,
+		.func = LED_MODEM_RED_FUNC_SEL,
+		.active_low = 0,
+	},
+	#if 1 //CONFIG_MIN_VERSION
+	{
+		.name = "modem_g_led",	
+			.pin_select = 0,/*gpio*/
+		.gpio = PIN_LED_MODEM_GREEN,
+		.func = LED_MODEM_GREEN_FUNC_SEL,
+		.active_low = 0,
+	},
+	{
+		.name = "modem_b_led",
+		.pin_select = 0,/*gpio*/
+		.gpio = PIN_LED_MODEM_BLUE,
+		.func = LED_MODEM_BLUE_FUNC_SEL,
+		.active_low = 0,
+	},
+	#endif
+	{
+		.name = "eth_led",
+		.pin_select = 0,/*gpio*/
+		.gpio = PIN_LED_ETH,
+		.func = LED_ETH_FUNC_SEL,
+		.active_low = 0,
+	},
+	{
+		.name = "wifi_led",	
+		.pin_select = 0,/*gpio*/
+		.gpio = PIN_LED_WIFI,
+		.func = LED_WIFI_FUNC_SEL,
+		.active_low = 0,
+	},
+	{
+		.name = "battery_r_led",			
+		.pin_select = 0,/*gpio*/
+		.gpio = PIN_LED_BATTARY_RED,
+		.func = LED_BATTARY_RED_FUNC_SEL,
+		.active_low = 0,
+		.default_state=LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name = "battery_g_led",
+		.pin_select = 0,/*gpio*/
+		.gpio = PIN_LED_BATTARY_GREEN,
+		.func = LED_BATTARY_GREEN_SEL,
+		.active_low = 0,
+		//.hw_timer = 1,
+		//.retain_state_suspended = 1,
+	}/*,
+	{
+		.name = "sink1",
+		.pin_select = 1,
+		//.gpio = PIN_LED_BATTARY_GREEN,
+		//.func = LED_BATTARY_GREEN_SEL,
+		.active_low = 0,
+		//.hw_timer = 1,
+		//.retain_state_suspended = 1,
+	}*/
+	
+};
+
+struct gpio_led new_ver_leds[]={
+	{
+		.name = "modem_r_led",
+		.pin_select = 0,/*gpio*/
+		.gpio = ZX29_GPIO_123,
+		.func = GPIO123_GPIO123,
+		.active_low = 0,
+	},
+	#if 1
+	{
+		.name = "modem_g_led",	
+			.pin_select = 0,/*gpio*/
+		.gpio = ZX29_GPIO_46,
+		.func = GPIO46_GPIO46,
+		.active_low = 0,
+	},
+	{
+		.name = "modem_b_led",
+		.pin_select = 0,/*gpio*/
+		.gpio = ZX29_GPIO_122,
+		.func = GPIO122_GPIO122,
+		.active_low = 0,
+	},
+	#endif
+	{
+		.name = "eth_led",
+		.pin_select = 0,/*gpio*/
+		.gpio = ZX29_GPIO_121,
+		.func = GPIO121_GPIO121,
+		.active_low = 0,
+	},
+	{
+		.name = "wifi_led",	
+		.pin_select = 0,/*gpio*/
+		.gpio = ZX29_GPIO_124,
+		.func = GPIO124_GPIO124,
+		.active_low = 0,
+	},
+	{
+		.name = "battery_r_led",			
+		.pin_select = 0,/*gpio*/
+		.gpio = ZX29_GPIO_73,
+		.func = GPIO73_GPIO73,
+		.active_low = 0,
+		.default_state=LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name = "battery_g_led",
+		.pin_select = 0,/*gpio*/
+		.gpio = PIN_LED_BATTARY_GREEN,
+		.func = LED_BATTARY_GREEN_SEL,
+		.active_low = 0,
+		//.hw_timer = 1,
+		//.retain_state_suspended = 1,
+	}/*,
+	{
+		.name = "sink1",
+		.pin_select = 1,
+		//.gpio = PIN_LED_BATTARY_GREEN,
+		//.func = LED_BATTARY_GREEN_SEL,
+		.active_low = 0,
+		//.hw_timer = 1,
+		//.retain_state_suspended = 1,
+	}*/
+	
+};
+
+extern  int  platform_gpio_blink_set(unsigned pin_sel,unsigned gpio, int state,
+			unsigned long *delay_on, unsigned long *delay_off);
+
+static struct gpio_led_platform_data leds_data =
+{
+	.num_leds =sizeof(new_ver_leds)/sizeof(new_ver_leds[0]) ,
+	.leds = new_ver_leds,
+	.gpio_blink_set=platform_gpio_blink_set,
+
+};
+
+static struct platform_device leds_device =
+{
+	.name		= "leds-gpio",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &leds_data,
+	},
+};
+#endif
+
+
+#ifdef CONFIG_KEYBOARD_ZX_INT
+/* --------------------------------------------------------------------
+ *  Keypad (power_on, ufi, ufi_reset) for ufi
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_ARCH_ZX297520V3_CPE_SWITCH)
+	static struct gpio_keys_button zx29_keypad_int[] = {
+		{
+			.gpio		= PIN_KPD_WPS,
+			.active_low = 1,
+			.desc		= "kpd_wps",
+			.code		= KEY_KPEQUAL,	 
+			.gpio_sel_gpio = KPD_WPS_FUNC_GPIO,
+			.gpio_sel_int = KPD_WPS_FUNC_INT,
+		},
+		{
+			.gpio		= PIN_KPD_RST,
+			.active_low = 1,
+			.desc		= "kpd_reset",
+			.code		= KEY_KPPLUSMINUS,	 
+			.gpio_sel_gpio = KPD_RST_FUNC_GPIO,
+			.gpio_sel_int = KPD_RST_FUNC_INT,
+		},
+		{
+			.gpio		= PIN_KPD_WIFI,
+			.active_low = 1,
+			.desc		= "kpd_wifi",
+			.code		= KEY_PAUSE,   
+			.gpio_sel_gpio = KPD_WIFI_FUNC_GPIO,
+			.gpio_sel_int = KPD_WIFI_FUNC_INT,
+		},
+	};
+#else
+	static struct gpio_keys_button zx29_keypad_int[] = {
+		{
+			.active_low = 1,				/*�Ƿ�͵�ƽ��Ч��1: ����Ϊ�͵�ƽ  0: ����Ϊ�ߵ�ƽ*/
+			.desc		= "kpd_power",
+			.code		= KEY_POWER 		/* power: 116 */,
+			.use_pmu_pwron = 1, 			/*true: use pmu pwron interrupt fase: use zx297520v2 ext int*/
+			/*
+			// unnecessary for the situation of (.use_pmu_pwron = 1)
+			.gpio		= PIN_KPD_POWER,
+			.gpio_sel_gpio = KPD_POWER_FUNC_GPIO,
+			.gpio_sel_int = KPD_POWER_FUNC_INT,
+			*/
+		},
+		#if 1
+	{
+		.gpio		= ZX29_GPIO_48,
+		.active_low	= 1,
+		.desc       = "kpd_wps",
+		.code       = KEY_KPEQUAL,       /* wps: 117 */
+		.gpio_sel_gpio = GPIO48_GPIO48,
+		.gpio_sel_int = GPIO48_EXT_INT1,
+    },
+	#endif
+
+    #if 1
+	{
+		.gpio		= ZX29_GPIO_53,
+		.active_low	= 1,
+		.desc       = "kpd_reset",
+		.code       = KEY_KPPLUSMINUS,   /* reset: 118 */
+		.gpio_sel_gpio = GPIO53_GPIO53,
+		.gpio_sel_int = GPIO53_EXT_INT6,
+    },
+	#endif
+	};
+#endif
+
+
+static struct gpio_keys_platform_data zx29_keypad_int_data = {
+	.buttons	= zx29_keypad_int,
+	.nbuttons	= ARRAY_SIZE(zx29_keypad_int),
+};
+
+static struct platform_device zx29_keypad_int_device ={
+	.name 	= 	"zx29_keypad_int",
+	.id 	=	-1,
+	.dev	= 	{
+		.platform_data = &zx29_keypad_int_data,
+	}
+};
+#endif
+
+#ifdef CONFIG_KEYBOARD_ZX_5x6
+static struct zx29_5x6_keypad_platform_data zx29_5x6_keypad_data = {
+	.key_map = {
+		{11,  12,  13,  14,  15,  16},
+		{21,  22,  23,  24,  25,  26},
+		{31,  32,  33,  34,  35,  36},
+		{41,  42,  43,  44,  45,  46},
+		{51,  52,  53,  54,  55,  56}
+	},
+	.pin_col_row = {83, 84, 85, 86},
+};
+
+static struct resource kpd5x6_resources[] = {
+	{
+		.start	= KEYPAD_INT,
+		.end	= KEYPAD_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device zx29_5x6_keypad_device ={
+	.name 	= 	"zx29_keypad",
+	.id 	=	0,
+	.resource		= kpd5x6_resources,
+	.num_resources	= ARRAY_SIZE(kpd5x6_resources),
+	.dev	= {
+        .platform_data = &zx29_5x6_keypad_data,
+    }
+};
+#endif
+
+#ifdef CONFIG_ZX29_GMAC
+/* gmac*/
+#if 0
+static struct resource gmac_resources[] = {
+	[0] = {
+		.start	= ZX_GMAC_BASE,
+		.end	= ZX_GMAC_BASE + SZ_8K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= GMAC_INT,
+		.end	= GMAC_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+#endif
+#if 1
+static struct resource zx29_gmac_resources[] = {
+	[0] = {
+		.start	= ZX_GMAC_BASE,
+		.end	= ZX_GMAC_BASE + SZ_8K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+#if 0
+	[1] = {
+		.name   = "gmac_int",
+		.start	= GMAC_INT,
+		.end	= GMAC_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.name   = "phy_int",
+		.start	= GMACPHY_INT,
+		.end	= GMACPHY_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+#endif
+};
+#endif
+static struct gmac_platform_data zx29_gmac_data = {
+#if defined(CONFIG_RTK8306E_PHY)
+	.nports		= 7,
+	.rmii_port	= 6,
+#endif
+#if defined(CONFIG_IP175L_PHY)
+	.nports 	= 6,
+	.rmii_port	= 4,
+#endif
+#if defined(CONFIG_ARCH_ZX297520V3_CPE)
+	.nports 	= 1,
+	.rmii_port	= 1,
+#endif
+	.port_mask  = 0xFFFFFF00,
+};
+
+static struct platform_device zx29_gmac_device = {
+	.name		= "zx29_gmac",
+	.id		= 0,
+	.resource	= zx29_gmac_resources,
+	.num_resources	= ARRAY_SIZE(zx29_gmac_resources),
+	.dev	 = {
+			.platform_data = &zx29_gmac_data,
+		    }
+};
+#endif
+
+#ifdef CONFIG_CHARGER_AW3215
+static struct  aw3215_platform_data aw3215_charger_platform = {
+    .gpio_chgen = ZX29_GPIO_126,
+    .gpio_chgen_gpio_sel = GPIO126_GPIO126,
+    .gpio_chgin = ZX29_GPIO_51,
+    .gpio_chgin_fun_sel = GPIO51_EXT_INT4,
+    .gpio_chgin_gpio_sel =GPIO51_GPIO51 ,
+    .gpio_chgctrl = ZX29_GPIO_130,/*not used*/
+    .gpio_chgctrl_gpio_sel = GPIO130_GPIO130,/*not used*/
+    .gpio_chgstate = ZX29_GPIO_54,
+    .gpio_chgstate_fun_sel = GPIO54_EXT_INT7,
+    .gpio_chgstate_gpio_sel = GPIO54_GPIO54,
+};
+
+static struct platform_device zx29_charger_device = {
+	.name		= "aw3215-charger",
+	.id		= 0,
+	.dev	 = {
+			.platform_data = &aw3215_charger_platform,
+		    }
+};
+
+
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_FT6X06
+static struct ft6x06_platform_data ft6x06_platform_priv_data = {
+	.irq_gpio = ZX29_GPIO_53,
+	.reset_gpio = ZX29_GPIO_121,
+	.irq_func = GPIO53_EXT_INT6,
+	.reset_func = GPIO121_GPIO121,
+};
+
+static struct platform_device ft6x06_platform_device = {
+	.name	= "ft6x06_ts",
+	.id		= 0,
+	.dev	= {
+			.platform_data = &ft6x06_platform_priv_data,
+		    }
+};
+
+#endif
+/* --------------------------------------------------------------------
+ *	----------  for  solution integration department ---------   end
+* -------------------------------------------------------------------- */
+
+
+/*
+ *  device tab used by board_init()
+ */
+struct platform_device *zx29_device_table[] __initdata={
+/* --------------------------------------------------------------------
+ *	----------  for  solution integration department ---------   start
+* -------------------------------------------------------------------- */
+#ifdef CONFIG_SERIAL_ZX29_UART
+	//&zx29_uart0_device,
+	&zx29_uart1_device,
+	//&zx29_uart2_device,
+#endif
+#ifdef CONFIG_MTD_NAND_DENALI
+	&zx29_device_nand,
+#endif
+#ifdef CONFIG_DWC_OTG_USB
+	&zx29_usb0_device,
+#endif
+#ifdef CONFIG_USB_DWC_OTG_HCD
+	&zx29_usb1_device,
+#endif
+#ifdef CONFIG_MTD_ZXIC_SPIFC
+	&zx29_device_spi_nand,
+#endif
+
+#ifdef CONFIG_SPI_ZXIC_NOR
+	&zx29_device_spi_nor,
+#endif
+
+
+#ifdef CONFIG_ZX29_DMA
+	&zx29_dma_device,
+#endif
+
+#ifdef CONFIG_MMC_ZX29
+    &zx29_sdmmc0_device,
+    //&zx29_sdmmc1_device,
+#endif
+
+#ifdef CONFIG_I2C_ZX29
+
+#ifdef zx29_pmic_i2c
+	&zx29_pmic_i2c_device,
+#endif
+
+#ifndef CONFIG_ARCH_ZX297520V3_CPE_SWITCH
+#ifdef zx29_I2C0
+	//&zx29_i2c0_device,
+#endif
+#endif
+
+#endif
+
+#ifdef CONFIG_SPI_ZX29
+	&zx29_ssp0_device,
+	/* &zx29_ssp1_device, */
+#endif
+
+#ifdef CONFIG_SPI_GPIO
+	&zx29_spi_gpio_dev0,
+	&zx29_spi_gpio_dev1,
+#endif
+
+#ifdef CONFIG_RPM_ZX29
+	&zx29_icp_m0_device,
+	&zx29_icp_ps_device,
+#endif
+
+#ifdef CONFIG_ZX29_WATCHDOG
+	&zx29_wdt_device,
+#endif
+
+#ifdef CONFIG_KEYBOARD_ZX_5x6
+	&zx29_5x6_keypad_device,
+#endif
+
+#ifdef CONFIG_KEYBOARD_ZX_INT
+    &zx29_keypad_int_device,
+#endif
+
+#ifdef CONFIG_CHARGER_AW3215
+       &zx29_charger_device,
+#endif
+
+#ifdef CONFIG_LEDS_GPIO
+       &leds_device,
+#endif
+
+#ifdef CONFIG_ZX29_GMAC
+ 	&zx29_gmac_device,
+#endif
+
+#if (defined CONFIG_SND_SOC_ZX_I2S) || (defined CONFIG_SND_SOC_ZX_I2S_MODULE)
+#ifdef zx29_I2S0
+	&zx29_i2s0_device,
+#endif
+#ifdef zx29_I2S1
+	&zx29_i2s1_device,
+#endif
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_FT6X06
+ 	&ft6x06_platform_device,
+#endif
+
+#if (defined CONFIG_SND_SOC_ZX_VOICE) || (defined CONFIG_SND_SOC_ZX_VOICE_MODULE)
+	&voice_asoc_device,
+#endif
+
+#if (defined CONFIG_SND_SOC_ZX_PCM) || (defined CONFIG_SND_SOC_ZX_PCM_MODULE)
+	&zx29_asoc_dma,
+#endif
+#if (defined CONFIG_SND_SOC_ZX297520V3) || (defined CONFIG_SND_SOC_ZX297520V3_MODULE)
+	&zx29_audio,
+#endif
+};
+
+unsigned int zx29_device_table_num=ARRAY_SIZE(zx29_device_table);
+
+#if (defined CONFIG_SPI_ZX29) || (defined CONFIG_SPI_GPIO)
+struct zx29_lcd_platform_data lead_lcd_platform = {
+	.spi_dcx_gpio = PIN_SPI_DCX,
+	.spi_dcx_gpio_fun_sel = SPI_DCX_FUNC_SEL,
+	.lcd_blg_gpio = PIN_LCD_BLG,
+	.lcd_blg_gpio_fun_sel = LCD_BLG_FUNC_SEL,
+	.lcd_rst_gpio = PIN_LCD_RST,
+	.lcd_rst_gpio_fun_sel =LCD_RST_FUNC_SEL,
+};
+
+static const struct spi_config_chip lead_lcd_chip_info = {
+	.com_mode = DMA_TRANSFER,
+	.iface = SPI_INTERFACE_MOTOROLA_SPI,
+	.hierarchy = SPI_MASTER,
+	.slave_tx_disable = 1,//DO_NOT_DRIVE_TX
+	.rx_lev_trig = SPI_RX_4_OR_MORE_ELEM,
+	.tx_lev_trig = SPI_TX_4_OR_MORE_EMPTY_LOC,
+//	.ctrl_len = SSP_BITS_8,
+//	.wait_state = SSP_MWIRE_WAIT_ZERO,
+//	.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
+//	.cs_control = null_cs_control,
+};
+#ifdef CONFIG_SLIC_TW
+
+
+static const struct spi_config_chip slic_chip_info = {
+	.com_mode = DMA_TRANSFER,
+	.iface = SPI_INTERFACE_MOTOROLA_SPI,
+	.hierarchy = SPI_MASTER,
+	.slave_tx_disable = 1,//DO_NOT_DRIVE_TX
+	.rx_lev_trig = SPI_RX_4_OR_MORE_ELEM,
+	.tx_lev_trig = SPI_TX_4_OR_MORE_EMPTY_LOC,
+//	.ctrl_len = SSP_BITS_8,
+//	.wait_state = SSP_MWIRE_WAIT_ZERO,
+//	.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
+//	.cs_control = null_cs_control,
+};
+#endif
+static struct spi_board_info zx29_spi_devices[] = {
+#ifdef CONFIG_FB_LEADT15DS26
+    {
+        .modalias 	    = "lead_t15ds26",
+        .bus_num 	    = 0,
+        .chip_select 	= 0,
+        .max_speed_hz	= 13000000,
+        .mode		    = SPI_MODE_3,
+        .platform_data 	= &lead_lcd_platform,
+        .controller_data = &lead_lcd_chip_info,
+    },
+#endif
+#ifdef CONFIG_SLIC_TW
+    {
+        .modalias 	    = "slic_tw_spi",
+        .bus_num 	    = 0,
+        .chip_select 	= 0,
+        .max_speed_hz	= 8000000,
+        .mode		    = SPI_MODE_3,
+        .platform_data 	= NULL,
+        .controller_data = &slic_chip_info,
+    },
+#endif
+};
+void __init spi_add_devices(void)
+{
+	unsigned  devices_num = ARRAY_SIZE(zx29_spi_devices);
+    int ret = 0;
+	printk("spi_register_board_info success,devices_num=%d\n",devices_num);
+#ifdef CONFIG_SPI_GPIO
+	/* set cs pin function select */
+	zx29_gpio_config(25, GPIO25_GPIO25);
+	zx29_gpio_config(87, GPIO87_GPIO87);
+#endif
+	if (devices_num){
+		ret = spi_register_board_info(zx29_spi_devices, devices_num);
+		printk("spi_register_board_info success,ret=%d\n",ret);
+		if(ret)
+			BUG();
+	}
+}
+#endif
+
+#ifdef CONFIG_CHARGER_ZX234502
+
+#define ZX234502_BAT_VOLTAGE_LEN  21
+
+struct zx234502_bat_calibration zx234502_bat_volage_charge[]=
+{
+	{4100,100}, {4090,95}, {4080,90}, {4070,85}, {4060,80}, {4050,75},
+	{4012,70}, {3973,65}, {3935,60}, {3896,55}, {3860,50}, {3817,45},
+	{3775,40}, {3733,35}, {3692,30}, {3650,25}, {3610,20}, {3570,15},
+	{3530,12}, {3590,10}, {3450,5}
+};
+
+struct zx234502_bat_calibration zx234502_bat_volage_discharge[]=
+{
+	{4100,100}, {4090,95}, {4080,90}, {4070,85}, {4060,80}, {4050,75},
+	{4012,70}, {3973,65}, {3935,60}, {3896,55}, {3860,50}, {3817,45},
+	{3775,40}, {3733,35}, {3692,30}, {3650,25}, {3610,20}, {3570,15},
+	{3530,12}, {3590,10}, {3450,5}
+};
+
+static struct  zx234502_platform_data zx234502_charger_platform = {
+	.gpio_int		=	PIN_CHARGE_INT,  //gpio55
+	.gpio_int_fun_sel = CHARGE_INT_FUNC_SEL,
+	.charging         =  &zx234502_bat_volage_charge,
+	.charging_size = ZX234502_BAT_VOLTAGE_LEN,
+	.discharging      =  &zx234502_bat_volage_discharge,
+	.discharging_size = ZX234502_BAT_VOLTAGE_LEN,
+	.ts_flag = TRUE,
+	.boost_flag = FALSE,
+	.boost_cur_gpio1 = PIN_CHARGE_BOOST_GPIO1,/*GPIO39*/
+	.boost_gpio1_fun_sel = CHARGE_BOOST_GPIO1_FUNC_SEL,
+	.boost_cur_gpio2 = PIN_CHARGE_BOOST_GPIO2,/*GPIO40*/
+	.boost_gpio2_fun_sel = CHARGE_BOOST_GPIO2_FUNC_SEL,
+	.boost_cur_gpio3 = PIN_CHARGE_BOOST_GPIO3,/*GPIO41*/
+	.boost_gpio3_fun_sel = CHARGE_BOOST_GPIO3_FUNC_SEL,
+	.boost_loadswitch_gpio = PIN_CHARGE_BOOST_LOADSWITCH,/*GPIO38*/
+	.boost_loadswitch_fun_sel = CHARGE_BOOST_LOADSWITCH_FUNC_SEL,
+};
+
+#endif
+
+#ifdef CONFIG_TSC_ZX29
+u32 ts_temp_value_table[TS_ADC_TEMP_NUMBER][TS_ADC_TEMP_VOLTAGE_NUMBER]={
+{30,31,32,33,34,35,36,37,38,39,
+ 40,41,42,43,44,45,46,47,48,49,
+ 50,51,52,53,54,55,56,57,58,59,
+ 60,61,62,63,64,65,66,67,68,69,
+ 70,71,72,73,74,75,76,77,78,79,
+ 80,81,82,83,84,85,86,87,88,89,
+ 90,91,92,93,94,95,96,97,98,99,
+ 100,101,102,103,104,105,106,107,108,109,
+ 110,111,112,113,114,115,116,117,118,119,
+ 120,121,122,123,124,125},
+
+{802,783,764,746,727,709,692,674,657,640,
+ 624,607,591,576,561,545,531,516,502,489,
+ 475,462,449,437,425,413,402,390,379,369,
+ 358,348,338,329,320,311,302,293,285,277,
+ 269,262,254,247,240,234,227,221,215,209,
+ 203,197,192,187,181,176,172,167,162,158,
+ 154,150,146,142,138,134,131,127,124,121,
+ 117,114,111,108,106,103,100,98, 95, 93,
+ 90, 88, 86, 84, 82, 80, 78, 76, 74, 72,
+ 70, 69, 67, 65, 64, 62}
+};
+volatile u32 ts_adc_flag=2;// 2:adc2,others:adc1
+#endif
+
+
+#if 1
+/*
+ *  I2C  device tab used by board_init()
+ */
+#ifdef CONFIG_MFD_ZX234290_I2C
+static struct  zx234290_board zx234290_platform = {
+	.irq_gpio_num	    =	PIN_PMU_INT, //EX0_INT,
+    .irq_gpio_func      =   PMU_INT_FUNC_SEL,
+	.pshold_gpio_num    =   PIN_PMU_PSHOLD,
+	.pshold_gpio_func   =   PMU_PSHOLD_FUNC_SEL,
+	.irq_base	= 	ENT_ZX234290_IRQ_BASE,
+};
+#endif
+
+static struct i2c_board_info zx29_i2c0_devices[] = {
+#ifdef CONFIG_MFD_ZX234290_I2C
+	[0]={
+		I2C_BOARD_INFO("zx234290", 0x12),
+		.irq		= EX0_INT,
+		.platform_data 	= &zx234290_platform,
+	},
+#endif
+
+};
+
+static struct i2c_board_info zx29_i2c1_devices[] = {
+#ifdef CONFIG_CHARGER_ZX234502
+		{
+			I2C_BOARD_INFO("zx234502-charger", 0x13),
+			.irq		= EX5_INT,
+			.platform_data	= &zx234502_charger_platform,
+		},
+#endif
+#if (defined CONFIG_SND_SOC_ZX297520V3) || (defined CONFIG_SND_SOC_ZX297520V3_MODULE)
+		{
+			I2C_BOARD_INFO(CODEC_NAME, CODEC_ADDR),
+			.platform_data 	= ZX29_SND_CODEC_PDATA, //&snd_codec_pdata,
+		},
+#endif
+#ifdef CONFIG_CAMERA_DRV
+		{
+			I2C_BOARD_INFO("gc6133-sensor", 0x40),
+		},
+#endif
+#ifdef CONFIG_TOUCHSCREEN_FT6X06
+		{
+			I2C_BOARD_INFO("ft6x06_ts", 0x38),
+			.platform_data	= &ft6x06_platform_priv_data,
+		},
+#endif
+};
+
+void __init i2c_add_devices(void)
+{
+	unsigned  devices_num = 0;
+    int ret = 0;
+
+	/*
+	  *i2c devices on bus 0
+	  */
+	devices_num = ARRAY_SIZE(zx29_i2c0_devices);
+	if (devices_num){
+		ret = i2c_register_board_info(0,zx29_i2c0_devices, devices_num);
+		if(ret)
+			BUG();
+	}
+
+	/*
+	  *i2c devices on bus 1
+	  */
+	devices_num = ARRAY_SIZE(zx29_i2c1_devices);
+	if (devices_num){
+		ret = i2c_register_board_info(1,zx29_i2c1_devices, devices_num);
+		if(ret)
+			BUG();
+	}
+}
+#endif
diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/input/keyboard/zx29-keypad-int.c b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/input/keyboard/zx29-keypad-int.c
new file mode 100644
index 0000000..36cf8d9
--- /dev/null
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/input/keyboard/zx29-keypad-int.c
@@ -0,0 +1,537 @@
+/***********************************************************************
+* Copyright (C) 2016, Sanechips Corporation.
+*
+* File Name:  zx29-keypad-int.c
+* File Mark:
+* Description:
+* Others:
+* Version:  v1.0
+* Author:   qihongfang yuxiang lvfei ZhouTianbao
+* Date:     2017-2-28
+*
+* History 1:
+*     Date:
+*     Version:
+*     Author:
+*     Modification:
+**********************************************************************/
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <asm/irq.h>
+#include <linux/workqueue.h>
+
+#include <linux/gpio.h>
+#include <mach/gpio.h>
+#include <mach/pcu.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/delay.h>
+#include <linux/wakelock.h>
+
+#include <mach/irqs.h>
+#include <linux/mfd/zx234290.h>
+#include <linux/kthread.h>
+#include <linux/soc/zte/pm/drv_idle.h>
+
+/**********************************************************************/
+//#define ERROR_REGISTER_IRQ        -100
+
+#define KEY_STATUS_UP               0
+#define KEY_STATUS_DOWN             1   /*input×ÓϵͳÖÐvalueΪ1Êǰ´ÏÂ*/
+
+#define KEY_DELAY_TIME              30  /* ms */
+#define KEY_NUM					    30
+
+static struct input_dev *button_dev = NULL;
+
+typedef struct _zx234290_keypad
+{
+    struct zx234290 *zx234290;
+}zx234290_keypad_data;
+
+static zx234290_keypad_data zx234290_keypad;
+
+static spinlock_t kpd_lock;
+static volatile unsigned int key_active_count = 0;
+static struct wake_lock keypad_wake_lock;
+static struct semaphore kpd_sem;
+
+//#ifdef KPD_DEBUG
+struct key_info
+{
+    unsigned int index;
+	unsigned int code;
+	int value;
+};
+struct key_info key_info_tab[KEY_NUM]=
+{
+    {0},
+};
+static unsigned int key_info_idx = 0;
+static unsigned int key_info_counter = 0;
+//#endif
+
+static int zx29_kpd_queue(unsigned int code, int value)
+{
+    key_info_tab[key_info_idx].code = code;
+    key_info_tab[key_info_idx].value= value;
+    key_info_tab[key_info_idx].index = key_info_counter;
+    key_info_idx++;
+    key_info_counter++;
+    if(key_info_idx >= KEY_NUM)
+    {
+        key_info_idx = 0;
+    }
+    return 0;
+}
+
+static void zx29_key_set_active(void)
+{
+	spin_lock(&kpd_lock);
+
+    if(key_active_count == 0)
+    {
+		zx_cpuidle_set_busy(IDLE_FLAG_KPD);
+		wake_lock(&keypad_wake_lock);
+    }
+    key_active_count++;
+
+	spin_unlock(&kpd_lock);
+}
+
+static void zx29_key_set_idle(void)
+{
+	spin_lock(&kpd_lock);
+
+    key_active_count--;
+    if(key_active_count == 0)
+    {
+    	wake_unlock(&keypad_wake_lock);
+		zx_cpuidle_set_free(IDLE_FLAG_KPD);
+    }
+
+	spin_unlock(&kpd_lock);
+}
+
+/*******************************************************************************
+* Function: zx29_kpd_get_keystate
+* Description:    Test key state
+* Parameters:
+*          Input:
+*       Output:
+* Returns:  0: key down µÍµçƽ(press)    1: key up ¸ßµçƽ(release)
+* Others:
+*   zx29_gpio_config(unsigned int gpio, unsigned int value)  ÉèÖø´ÓÃ
+*   value:  0:GPIO    1:FUNCTION
+********************************************************************************/
+
+static int zx29_kpd_get_keystate(int gpioNum,unsigned int gpio_sel_gpio,unsigned int gpio_sel_int)
+{
+    unsigned int gpio_state = GPIO_HIGH;
+    int irq;
+
+    zx29_gpio_config(gpioNum, gpio_sel_gpio);
+    irq = gpio_to_irq(gpioNum);
+    //pcu_clr_irq_pending(irq);
+    zx29_gpio_set_direction(gpioNum, GPIO_IN);
+    msleep(KEY_DELAY_TIME);
+    gpio_state = gpio_get_value(gpioNum);
+    /* msleep(30); */
+    zx29_gpio_config(gpioNum, gpio_sel_int);/******qhf***int****/
+    //pcu_clr_irq_pending(irq);
+
+    //printk(KERN_INFO "gpio state=%d.\n",gpio_state);
+
+    return gpio_state;  /* 0: µÍµçƽ(press), 1:¸ßµçƽ(release) */
+
+}
+
+static irqreturn_t zx29_kpd_pwron_inform(int irq, void *dev_id)
+{
+	up(&kpd_sem);
+	return IRQ_HANDLED;
+}
+
+/*******************************************************************************
+* Function: zx29_kpd_pwron_thread
+* Description:
+* Parameters:
+*          Input:
+*       Output:
+* Returns:
+* Others:
+********************************************************************************/
+#define USE_EXT_DEV
+#ifdef USE_EXT_DEV
+//extern struct input_dev *button5x6_dev;
+extern struct input_dev *input_dev_table[32];
+#endif
+int zx29_kpd_pwron_thread(void *dev_id)
+{
+	struct gpio_keys_button *buttons = (struct gpio_keys_button *)dev_id;
+	int ret = 0;
+	unsigned char status = 0;
+
+	struct sched_param param;
+	param.sched_priority = 33;
+	sched_setscheduler(current, SCHED_FIFO, &param);
+
+	while (!kthread_should_stop()) {
+		down(&kpd_sem);
+
+		zx29_key_set_active();
+
+		msleep(10);
+		ret = zx234290_i2c_read_simple(ZX234290_REG_ADDR_STSA, &status);
+		if(ret)
+		{
+			printk(KERN_INFO "kpd read reg return=%d.\n", ret);
+		}
+		else if((status >> ZX234290_STATUSA_POWERON_LSH) & 0x1)
+		{
+#ifdef USE_EXT_DEV
+			if (input_dev_table[1]) {
+				set_bit(buttons->code, input_dev_table[1]->keybit);
+				input_report_key(input_dev_table[1], buttons->code, KEY_STATUS_DOWN);
+				input_sync(input_dev_table[1]);
+			}
+#endif
+			input_report_key(button_dev, buttons->code, KEY_STATUS_DOWN);
+			input_sync(button_dev);
+
+			zx29_kpd_queue(buttons->code, KEY_STATUS_DOWN);
+			printk(KERN_INFO "kpd down code=%d .\n",buttons->code);
+
+			while(1)
+			{
+				msleep(60);
+
+				ret = zx234290_i2c_read_simple(ZX234290_REG_ADDR_STSA, &status);
+				if(ret)
+				{
+					printk(KERN_INFO "kpd read reg return=%d.\n", ret);
+					break;
+				}
+				//printk(KERN_INFO "kpd reg status=%d.\n", status);
+
+				if(((status>>ZX234290_STATUSA_POWERON_LSH)&0x1) == 0x0)
+				{
+#ifdef USE_EXT_DEV
+					if (input_dev_table[1]) {
+						input_report_key(input_dev_table[1], buttons->code, KEY_STATUS_UP);
+						input_sync(input_dev_table[1]);
+					}
+#endif
+					input_report_key(button_dev, buttons->code, KEY_STATUS_UP);
+					input_sync(button_dev);
+
+					zx29_kpd_queue(buttons->code, KEY_STATUS_UP);
+					printk(KERN_INFO "kpd up code=%d.\n",buttons->code);
+					break;
+				}
+			}
+		}
+		else
+		{
+			printk(KERN_INFO "kpd power key noise.\n");
+		}
+
+		zx29_key_set_idle();
+	}
+
+	return 0;
+}
+
+static irqreturn_t zx29_kpd_irq_thread(int irq, void *dev_id)
+{
+    struct gpio_keys_button *buttons = (struct gpio_keys_button *)dev_id;
+    int gpio_val = 0;
+	int state;
+
+    zx29_key_set_active();
+
+    //printk(KERN_INFO "handle irq=%d.\n",irq);
+    gpio_val = zx29_kpd_get_keystate(buttons->gpio,buttons->gpio_sel_gpio,buttons->gpio_sel_int);
+	state = !!gpio_val ^ !!buttons->active_low;
+
+    zx29_gpio_set_inttype(buttons->gpio,
+						  (gpio_val ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_LEVEL_HIGH));
+    //pcu_int_clear(irq);
+    //pcu_clr_irq_pending(irq);
+
+#ifdef USE_EXT_DEV
+	if (input_dev_table[1]) {
+		set_bit(buttons->code, input_dev_table[1]->keybit);
+		input_report_key(input_dev_table[1], buttons->code, state);
+		input_sync(input_dev_table[1]);
+	}
+#endif
+
+    input_report_key(button_dev, buttons->code, state);  //Éϱ¨key ¼üÖµ
+    //key_info_tab[key_num].lastStatus = state;
+    input_sync(button_dev);
+    zx29_kpd_queue(buttons->code, state);
+    printk(KERN_INFO "kpd %s code=%d, irq=%d.\n",
+			(state ? "down" : "up"),
+			buttons->code,
+			irq);
+
+    //enable_irq(irq);    //´ò¿ªÖжÏ
+
+    zx29_key_set_idle();
+    return IRQ_HANDLED;
+}
+
+/*******************************************************************************
+* Function: zx29_kpd_irq_handler
+* Description: clear irq , wake thread irq
+* Parameters:
+*          Input:
+*       Output:
+********************************************************************************/
+static irqreturn_t zx29_kpd_irq_handler(int irq, void *dev_id)
+{
+    //disable_irq_nosync(irq);
+    //pcu_int_clear(irq);
+    pcu_clr_irq_pending(irq);
+
+    //printk(KERN_INFO "kpd handler irq=%d.\n", irq);
+
+    return IRQ_WAKE_THREAD;
+}
+
+/*******************************************************************************
+* Function: zx29_kpd_request_irqs
+* Description:
+* Parameters:
+*          Input:
+*       Output:
+********************************************************************************/
+static int zx29_kpd_request_irqs(struct gpio_keys_platform_data *pdata )
+{
+    int ret = -1;
+    struct gpio_keys_button *buttons = pdata->buttons;
+    int keypad_num = pdata->nbuttons;
+    int irq_num = 0;
+
+    for(keypad_num = 0; keypad_num < pdata->nbuttons; keypad_num++)
+    {
+        if(buttons[keypad_num].use_pmu_pwron == 0)
+        {
+			ret = gpio_request(buttons[keypad_num].gpio, buttons[keypad_num].desc);
+			if (ret < 0) {
+				printk(KERN_ERR "kpd request gpio%d failed.\n", buttons[keypad_num].gpio);
+				break;
+			}
+            zx29_gpio_config(buttons[keypad_num].gpio,buttons[keypad_num].gpio_sel_int);
+			/* some switch may be active before booting. use level irq to avoid lack of falling edge. */
+            zx29_gpio_set_inttype(buttons[keypad_num].gpio,
+					(buttons[keypad_num].active_low ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_LEVEL_HIGH));
+            if(buttons[keypad_num].code == KEY_KPEQUAL || buttons[keypad_num].code == KEY_KPPLUSMINUS)
+                zx29_gpio_pd_pu_set(buttons[keypad_num].gpio, IO_CFG_PULL_UP);
+            else
+                zx29_gpio_pd_pu_set(buttons[keypad_num].gpio, 0);
+
+            msleep(1); /* wait for stable input */
+
+            irq_num = gpio_to_irq(buttons[keypad_num].gpio);
+            /*
+            if(irq_num > 0){
+                printk(KERN_INFO "zx29_kpd_request_irqs error irq_num=%d.\n",irq_num);
+            }
+            */
+
+            /* pcu_clr_irq_pending(irq_num); */
+            ret = request_threaded_irq(irq_num, NULL, zx29_kpd_irq_thread, IRQF_ONESHOT/*IRQF_TRIGGER_HIGH | IRQF_NO_THREAD*/,
+                buttons[keypad_num].desc, &buttons[keypad_num]);
+			irq_set_irq_wake(irq_num, 1);
+        }
+        else
+        {
+			sema_init(&kpd_sem, 0);
+			kthread_run(zx29_kpd_pwron_thread, &buttons[keypad_num], "kpd_pwron_thread");
+
+			irq_num = ENT_ZX234290_IRQ_BASE + ZX234290_INT_PWRON;
+			ret = request_threaded_irq(irq_num, NULL, zx29_kpd_pwron_inform, 0,
+							buttons[keypad_num].desc, &buttons[keypad_num]);
+        }
+        if(ret)
+        {
+            return ret;
+        }
+        printk(KERN_INFO "kpd request_irq irq_num=%d.\n", irq_num);
+    }
+
+    return ret;
+}
+
+/*******************************************************************************
+* Function: zx29_kpd_probe
+* Description:
+* Parameters:
+*          Input:
+*        Output:
+* Returns:
+********************************************************************************/
+static int zx29_kpd_probe(struct platform_device *pdev)
+{
+    int error = -1;
+    static int i = 0;
+	struct input_handle *handle;
+    struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+    struct gpio_keys_button *buttons = pdata->buttons;
+    zx234290_keypad.zx234290 = dev_get_drvdata(pdev->dev.parent);
+
+    button_dev = input_allocate_device();
+    if(!button_dev)
+    {
+        printk("allocate_device error.\n");
+        return error;
+    }
+    button_dev->name = pdev->name;
+    button_dev->evbit[0] = BIT_MASK(EV_KEY)|BIT_MASK(EV_REP);
+
+    for(i=0; i < pdata->nbuttons; i++)
+    {
+        set_bit(buttons[i].code,button_dev->keybit);
+    }
+
+    error = input_register_device(button_dev);
+    if(error)
+    {
+        printk("register device error\n");
+        goto err_free_dev;
+    }
+	handle = container_of(button_dev->h_list.next, struct input_handle, d_node);
+	/* printk(KERN_INFO "%s registered evdev %s/%p.\n", __FUNCTION__, handle->name, handle->private); */
+
+    platform_set_drvdata(pdev, button_dev);
+
+	spin_lock_init(&kpd_lock);
+	wake_lock_init(&keypad_wake_lock, WAKE_LOCK_SUSPEND, "keypad");
+    zx29_kpd_request_irqs(pdata);
+
+    return 0;
+
+err_free_dev:
+    input_free_device(button_dev);
+    return error;
+}
+
+
+/*******************************************************************************
+* Function: zx29_kpd_remove
+* Description:
+* Parameters:
+*          Input:
+*        Output:
+* Returns:
+********************************************************************************/
+static int zx29_kpd_remove(struct platform_device *pdev)
+{
+    struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+    struct gpio_keys_button *buttons = pdata->buttons;
+    static struct input_dev *button_dev = NULL;
+    int i = 0;
+    int irq_num;
+
+    for(i = 0; i < pdata->nbuttons; i++){
+        irq_num = gpio_to_irq(buttons[i].gpio);
+        if(irq_num < 0){
+            printk(KERN_INFO "%s error keypad_num=%d.\n", __FUNCTION__, i);
+        }
+
+    	free_irq(irq_num,NULL);
+		gpio_free(buttons[i].gpio);
+    }
+    button_dev = (struct input_dev *)platform_get_drvdata(pdev);
+    input_free_device(button_dev);
+    button_dev = NULL;
+
+    zx234290_keypad.zx234290 = NULL;
+
+    wake_lock_destroy(&keypad_wake_lock);
+
+    return 0;
+}
+
+static int zx29_kpd_resume(struct platform_device *pdev)
+{
+    struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+    struct gpio_keys_button *buttons = pdata->buttons;
+    int i = 0;
+    int irq_num = 0;
+
+    for(i = 0; i < pdata->nbuttons; i++){
+
+        irq_num = gpio_to_irq(buttons[i].gpio);
+        if(irq_num < 0){
+            printk(KERN_INFO "%s error keypad_num=%d.\n", __FUNCTION__, i);
+        }
+        if(irq_num != 0){
+            enable_irq(irq_num);
+        }
+
+    }
+    printk(KERN_INFO "%s\n", __FUNCTION__);
+    return 0;
+}
+
+static int zx29_kpd_suspend(struct platform_device *pdev, pm_message_t state)
+{
+    struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+    struct gpio_keys_button *buttons = pdata->buttons;
+    int i = 0;
+    int irq_num = 0;
+
+    for(i = 0; i < pdata->nbuttons; i++){
+        irq_num = gpio_to_irq(buttons[i].gpio);
+        if(irq_num < 0){
+            printk(KERN_INFO "%s error keypad_num=%d.\n", __FUNCTION__, i);
+        }
+        if(irq_num != 0){
+            disable_irq(irq_num);
+        }
+
+    }
+    printk(KERN_INFO "%s\n", __FUNCTION__);
+    return 0;
+}
+
+static struct platform_driver zx29_kpd_driver =
+{
+    .probe  = zx29_kpd_probe,
+    .remove = zx29_kpd_remove,
+    .driver =
+    {
+        .name   =   "zx29_keypad_int",
+        .owner  =   THIS_MODULE,
+    },
+    //.resume = zx29_kpd_resume,
+    //.suspend    = zx29_kpd_suspend,
+};
+
+static int __init zx29_kpd_init(void)
+{
+    return platform_driver_register(&zx29_kpd_driver);
+}
+
+static void __exit zx29_kpd_exit(void)
+{
+    platform_driver_unregister(&zx29_kpd_driver);
+}
+
+module_init(zx29_kpd_init);
+module_exit(zx29_kpd_exit);
+
+MODULE_AUTHOR("Sanechips");
+MODULE_DESCRIPTION("Sanechips Keypad Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/ethernet/zte/zx29_gmac.c b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/ethernet/zte/zx29_gmac.c
new file mode 100755
index 0000000..9702de5
--- /dev/null
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/ethernet/zte/zx29_gmac.c
@@ -0,0 +1,1356 @@
+/*

+ * Ethernet driver for zte zx2975xx gmac on chip network device

+ * (c)2008 http://www.zte.com.cn

+ * Authors:	zhang dongdong <zhang.dongdong16@zte.com.cn>

+ *

+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License

+ * as published by the Free Software Foundation; either version

+ * 2 of the License, or (at your option) any later version.

+ */

+#include <linux/kernel.h>

+#include <linux/module.h>

+#include <linux/interrupt.h>

+#include <linux/types.h>

+#include <linux/delay.h>

+#include <linux/init.h>

+#include <linux/spinlock.h>

+#include <linux/netdevice.h>

+#include <linux/etherdevice.h>

+#include <linux/phy.h>

+#include <linux/platform_device.h>

+#include <linux/gmac/gmac.h>

+#include <linux/gpio.h>

+#include "zx29_gmac.h"

+

+#define gmac_printk(_format, _args...)		do{printk(KERN_INFO"gmac," _format "\n",##_args);}while(0)

+

+struct tasklet_struct	*g_gmac_tasklet = NULL;

+

+static void gmac_hw_deinit(struct net_device *dev);

+

+struct zx29_gmac_dev	*g_gmac_dev = NULL;

+

+static u8 zx29_gmac_addr[MAC_ADDR_LENTH] = {0xec,0x1d,0x7f,0xb0,0x2f,0x32};

+

+// È¡µÃµ±Ç°µÄ½ÓÊÕÃèÊö·û

+static struct bd_rx *get_rx_bd(struct net_device *dev)

+{

+    struct zx29_gmac_dev* prv 	= (struct zx29_gmac_dev*)netdev_priv(dev);

+    int   n						= prv->rx_bd_offset;

+    struct bd_rx *d				= (struct bd_rx*)prv->dma_rx_vir;

+

+    if(d[n].RDES0 & DMA_OWNER) 

+    {

+        return 0;

+    }

+    else	

+    {

+        return &d[n];

+    }

+}

+

+static inline int mod_sub(int left, int right, int mod)

+{

+    return (mod - right + left) % mod;

+}

+

+// È¡µÃµ±Ç°µÄ·¢ËÍÃèÊö·û

+static inline struct bd_tx *get_tx_bd(struct net_device *dev)

+{

+    struct zx29_gmac_dev* prv 	= (struct zx29_gmac_dev*)netdev_priv(dev);

+    int   n						= prv->tx_bd_offset;

+    struct bd_tx *d				= (struct bd_tx*)prv->dma_tx_vir;

+	

+    if( mod_sub(prv->tx_bd_offset, prv->txed_bd, GMAC_TX_BD_NUM) > GMAC_TX_BD_NUM - 2 )  

+	{

+		return 0;

+	}

+		

+    if(d[n].TDES0 & DMA_OWNER) 	

+    {

+        return 0;

+    }

+    else

+    {

+        return &d[n];

+    }

+}

+

+// È¡µÃÒÑ·¢ËÍÃèÊö·û

+static struct bd_tx *get_txed_bd(struct net_device *dev)

+{

+    struct bd_tx *d;

+    struct zx29_gmac_dev* prv 	= (struct zx29_gmac_dev*)netdev_priv(dev);

+    int n						= prv->txed_bd;

+

+    d	= (struct bd_tx*)prv->dma_tx_vir;

+

+	if(n == prv->tx_bd_offset) return 0;

+	

+    if(d[n].TDES0 & DMA_OWNER)	return 0;

+	

+	if(d[n].skb == NULL) return 0; 

+

+    prv->txed_bd++;

+    prv->txed_bd %= GMAC_TX_BD_NUM;

+

+    return &d[n];

+}

+

+static void mac_init(struct net_device *dev)

+{

+    volatile unsigned *gmac = (unsigned*)dev->base_addr;

+    unsigned int i=0, j=0, mac_rst=0;

+

+    mac_provide_clock();

+#ifdef __DEAD_LOOP_POLL__                       //////¿ÉÄÜ»áÔì³ÉËÀÑ­»·ÎÞ·¨Í˳ö£¬Äں˳õʼ»¯ÎÞ·¨¼ÌÐø/////////

+    mac_reset();  								// ¿ØÖÆÆ÷¸´Î»

+    mac_set_gmii_mode();						// MII½Ó¿Ú

+    mac_wait_reset_finished();

+#else                                           /////ÒÔÏÂÐ޸ĴúÂëÐèÒª½øÐÐÑϸñ²âÊÔ////////

+    //LOG_INFO("wait for gmac reseting");

+    for(i=0; i<MAC_RESET_NUM; i++)              /////Èí¸´Î»³¢ÊÔ´ÎÊý/////

+    {

+        mac_reset();

+        mac_set_mii_mode();                 //ÉèÖÃΪmiiģʽ£¬10m»òÕß100m

+        for(j=0; j<MAC_WAIT_TIME; j++)          /////²éѯ¸´Î»×´Ì¬³¬Ê±¼ÆÊýÑ­»·1´ÎÊÇ0.1ms////////

+        {

+            printk(".");

+            if(!((MAC(0x1000)) & 1))

+            {

+                printk("ok\n");

+                mac_rst = 1;

+                goto mac_reset_option;

+            } 

+            udelay(100);                        ////µÈ´ý 0.1ms

+        }

+    }

+mac_reset_option:

+    if(!mac_rst)                                ////gmacÍø¿¨macоƬûÓи´Î»³É¹¦//////

+    {

+        printk("gmac reset failed!\n");

+    }

+#endif

+    while(mac_mii_is_busy());

+}

+

+static int gmac_init_rx_bd(struct net_device *dev, struct zx29_gmac_dev* prv)

+{

+    struct sk_buff	*skb = NULL;

+    struct bd_rx *rx  = (struct bd_rx *)prv->dma_rx_vir;

+    int 			i = 0;	

+

+    prv->rx_bd_offset		= 0;

+

+	for(i = 0; i < GMAC_RX_BD_NUM; i++)

+	{

+		// ½ÓÊÕÃèÊö·û³õʼ»¯

+		// ½ÓÊÕÃèÊö·ûµÄÊý¾Ý»º³åÇøÎª SKBµÄdata¶Î£¬¹ÊÏÈ·ÖÅäÏàÓ¦ÊýÁ¿µÄskb£¬

+		// ¹ÒÔÚ½ÓÊÕÃèÊö·û»·»ØÁ´±íÉÏ£¬µ±GMACÓ²¼þ½«Êý¾Ý±£´æºó£¬½«¸Ãskbȡϣ¬Ë͸øÐ­ÒéÉϲã

+		// Í¬Ê±ÒªÖØÐ·ÖÅäÒ»¸öSKB£¬ÔÙ¹Òµ½½ÓÊÕÃèÊö·û»·»ØÁ´±íÉÏ

+

+		skb = netdev_alloc_skb(dev, GMAC_FRAME_LEN + NET_IP_ALIGN);

+

+		if(unlikely(!skb))

+		{

+		   // LOG_ERR("kmalloc memory failed\n");

+			gmac_hw_deinit(dev);

+			return -1;

+		}

+

+		skb_reserve(skb, NET_IP_ALIGN);

+

+		rx[i].RDES0 	   |= DMA_OWNER;

+		rx[i].RDES1  = 0;

+		rx[i].RDES1 	   = GMAC_FRAME_LEN | 1 << 14;

+		rx[i].dma_buf		= virtaddr_to_phys((unsigned)skb->data);

+		rx[i].next			= prv->dma_rx_phy + ((i + 1) << 5);

+		rx[i].skb			= skb;

+#if 0

+		if(i%4 != 0)

+		{

+	       rx[i].RDES1  |= 0x80000000;

+		}

+#endif

+		dma_sync_single_for_device(&dev->dev, rx[i].dma_buf, GMAC_FRAME_LEN, DMA_TO_DEVICE);

+

+	}

+

+	// Ï´ÎÊǶÔÁ´±í½øÐл·»Ø´¦Àí

+	rx[GMAC_RX_BD_NUM-1].next			= prv->dma_rx_phy;

+	rx[GMAC_RX_BD_NUM-1].RDES1 			= GMAC_FRAME_LEN	  | 1 << 14 | 1 << 15;

+

+	return 0;

+}

+

+static void gmac_init_tx_bd(struct zx29_gmac_dev* prv)

+{

+    struct bd_tx *tx  = (struct bd_tx *)prv->dma_tx_vir;

+

+    int 			i = 0;

+

+    prv->tx_bd_offset		= 0;

+    prv->txed_bd			= 0;

+

+    for(i = 0; i < GMAC_TX_BD_NUM; i++)

+    {

+        // ·¢ËÍÃèÊö·û³õʼ»¯

+        // ·¢ËÍÃèÊö·ûµÄÊý¾Ý»º³åÇøÎª SKBµÄdata¶Î£¬¹Ê²»ÐèÒªÊý¾Ý»º³åÇø£¬

+        // ·¢ËÍʱ½«¸ÃSKBµÄÊý¾ÝÇø¹ÒÔÚ·¢ËÍÃèÊö·û»·»ØÁ´±íÉÏ£¬µ±GMACÓ²¼þ½«Êý¾ÝÊý¾Ý·¢Ëͺó£¬Ôݲ»´¦Àí£¬µÈ»·»ØÁ´±íÖØÐÂÈÆ»ØÊ±ÔÙ´¦Àí

+

+        tx[i].TDES0       	= (1 << 20 | 1 << 30);

+        tx[i].TDES1       	= GMAC_FRAME_LEN;

+        tx[i].next			= prv->dma_tx_phy + ((i + 1) << 5);

+    }

+

+    // Ï´ÎÊǶÔÁ´±í½øÐл·»Ø´¦Àí

+    tx[GMAC_TX_BD_NUM-1].next		    	= prv->dma_tx_phy;

+    tx[GMAC_TX_BD_NUM-1].TDES0            	= 1 << 20 | 1 << 21 | 1 << 30;	

+}

+

+static void gmac_stop(void* io)

+{

+	volatile unsigned *gmac = (unsigned*)io;

+

+    dma_disable();

+    mac_disable();

+    mac_int_disable();

+

+    // Çå¿Õ·¢ËÍFIFO

+    dma_clear_tx_fifo();

+    dma_wait_tx_fifo_cleared();

+}

+

+static void gmac_start(void* io)

+{

+	volatile unsigned *gmac = (unsigned*)io;

+

+    mac_int_enable();

+    dma_enable();

+    mac_enable();

+}

+

+static void gmac_trig_transmit(void* io)

+{

+    volatile unsigned *gmac 	= (unsigned*)io;

+    register unsigned status	= (MAC(0x1014) >> 20) & 0x07;

+    switch(status)

+    {

+        case 0:		// ´«ÊäÍ£Ö¹£»¸´Î»»òÕßÍ£Ö¹ÃüÁî·¢ËÍ

+            dma_enable();

+            break;

+        case 6:		// ¹ÒÆð£»´«ÊäÃèÊö·û²»¿ÉÓûòÕß´«Ê仺´æÏÂÒç¡£

+            dma_continue_tx();

+            break;

+        case 1:		// ÕýÔÚ½øÐУ»»ñÈ¡´«ÊäÃèÊö·û

+        case 2:		// ÕýÔÚ½øÐУ»µÈ´ý´«Êä״̬

+        case 3:		// ÕýÔÚ½øÐУ»´Ó·¢ËÍ»º´æ¶ÁÈ¡Êý¾Ý²¢·¢Ë͵½´«Êä FIFO(TxFIFO)

+        case 4:		// дÈëʱ¼ä´Á״̬

+        case 5:		// ±£Áô

+        case 7:		// ÔËÐУ»¹Ø±Õ´«ÊäÃèÊö·û¡£

+        default:

+            break;

+    }

+}

+

+static void gmac_trig_receive(void* io)

+{

+    volatile unsigned *gmac 	= (unsigned*)io;

+    register unsigned status	= (MAC(0x1014) >> 17) & 0x07;;

+    switch(status)

+    {

+        case 0:		// ֹͣ

+            dma_enable();

+            break;

+        case 4:		// ¹ÒÆð

+            dma_continue_rx();

+            break;

+        default:

+            break;

+    }

+}

+

+// ÉèÖÃÓ²¼þMACµØÖ·

+static inline void gmac_update_mac(struct net_device *dev)

+{

+    volatile unsigned *gmac = (unsigned*)dev->base_addr;

+    unsigned char *mac		= (unsigned char *)(dev->dev_addr);

+

+    MAC(0x0044)	= mac[0] | mac[1] << 8 | mac[2] << 16 | mac[3] << 24;

+    MAC(0x0040) = mac[4] | mac[5] << 8;

+

+    //LOG_INFO("MAC: %02X-%02X-%02X-%02X-%02X-%02X\n", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);

+}

+

+static void gmac_hw_deinit(struct net_device *dev)

+{

+    int 				i;

+    struct bd_rx 		*rx_bd;

+	struct bd_tx 		*tx_bd;

+    volatile unsigned 	*gmac	= (unsigned*)dev->base_addr;

+    struct zx29_gmac_dev *prv	= (struct zx29_gmac_dev*)netdev_priv(dev);

+

+    gmac_stop((void*)dev->base_addr);

+

+    // ×¢Òârx tx Ò»ÆðÏú»Ù

+    if(prv->dma_rx_phy) {

+        rx_bd   = (struct bd_rx*)prv->dma_rx_vir;

+

+        for(i = 0; i < GMAC_RX_BD_NUM; i++) {

+        	if(rx_bd[i].skb != NULL)      

+ 	           dev_kfree_skb_any(rx_bd[i].skb);

+        }

+

+		tx_bd   = (struct bd_tx*)prv->dma_tx_vir;

+		

+        for(i = 0; i < GMAC_TX_BD_NUM; i++) {

+        	if(tx_bd[i].skb != NULL)

+            	dev_kfree_skb_any(tx_bd[i].skb);

+        }

+

+       // dma_free_coherent(NULL, GMAC_BUF_LEN, prv->dma_rx_vir, prv->dma_rx_phy);   //ÊÍ·Ådma»º³åÇø

+    }

+

+    dma_set_tx_buffer(0);   //ÉèÖÃÊ׸öBDµÄ»º³åÇøÎª0£»

+    dma_set_rx_buffer(0);

+

+    prv->rx_bd_offset	= 0;

+    prv->tx_bd_offset	= 0;

+    prv->txed_bd		= 0;

+    prv->dma_rx_phy		= 0;

+    prv->dma_rx_vir		= 0;

+    prv->dma_tx_phy		= 0;

+    prv->dma_tx_vir		= 0;

+}

+

+void gmac_set_speed_duplex(struct net_device *dev, int speed, int duplex)

+{

+    unsigned			val;

+    struct zx_net_dev* 	prv 	= (struct zx_net_dev*)netdev_priv(dev);

+    volatile unsigned 	*gmac 	= (unsigned*)dev->base_addr;

+

+    val = MAC(0x0000) | 1<<11 | 1<<14;  // ĬÈÏΪ100Mȫ˫¹¤

+    if(SPEED_10 == speed)

+    {

+        val &= ~(1 << 14);                  // 10M

+    }

+    if(DUPLEX_HALF == duplex)

+    {

+        val &= (~(1 << 11));                    // °ëË«¹¤

+        val |= (1 << 16);

+    }

+    MAC(0x0000) = val;

+}

+

+static int gmac_hw_init(struct net_device *dev)

+{

+	int ret = -1;

+    unsigned 		val;

+

+    volatile unsigned *gmac	= (unsigned*)dev->base_addr;   //WL  ÍøÂçÉ豸µÄIO»ùµØÖ·

+    struct zx29_gmac_dev* prv 	= (struct zx29_gmac_dev*)netdev_priv(dev);

+

+	printk("cy: gmac_hw_init \n");

+    if(prv->dma_rx_phy) {

+		printk("cy: gmac_hw_init gmac_hw_deinit\n");

+        gmac_hw_deinit(dev);

+	}

+

+    prv->dma_rx_vir = prv->dma_rx_vir_init;

+	prv->dma_rx_phy = prv->dma_rx_phy_init;

+    prv->dma_tx_vir	= prv->dma_rx_vir + GMAC_RX_BUF_LEN;

+    prv->dma_tx_phy	= prv->dma_rx_phy + GMAC_RX_BUF_LEN;

+

+    // ¶ÔÃèÊö·ûÊý¾ÝÇøÇåÁã

+    memset(prv->dma_rx_vir, 0, GMAC_BUF_LEN);

+

+	//ec616000600086,should check init_rx result

+    ret = gmac_init_rx_bd(dev, prv);

+	if(ret < 0)

+	{

+		printk("hw_net_init,init_rx_bd fail\n");

+		return ret;

+	}

+    gmac_init_tx_bd(prv);

+

+    mac_init(dev);

+

+    /*¹Ø±ÕGMACËùÓй¦ÄÜ*/

+    dma_disable();

+    mac_disable();

+    mac_int_disable();

+

+    /*ÉèÖÃÍ»·¢´«Ê䳤¶È*/

+    val		 	= MAC(0x1000);

+    val			&= ~(0x3F << 8);

+    val			|=  (0x10 << 8);    //burst 16

+    MAC(0x1000)	 = val;

+

+    /*  ÉèÖýÓÊÕÓë·¢ËÍÃèÊö·û*/

+    dma_set_rx_buffer(prv->dma_rx_phy);

+    dma_set_tx_buffer(prv->dma_tx_phy);

+

+    mac_int_clear(0x0001FFFF);								// ÖжÏÇå³ý

+    while(mac_mii_is_busy());

+	

+	//set speed and duplex mode

+	gmac_set_speed_duplex(dev, prv->phydev->speed, prv->phydev->duplex);

+	

+    mac_rece_all_data();									// ½ÓÊÕËùÓÐÊý¾Ý

+    //gmac_set_filter(dev);                                 //²âÊÔʱ¿ÉÒÔ²»Óôò¿ª

+

+	gmac_start((void*)dev->base_addr);

+    return 0;

+}

+

+static int zx29mii_read(struct mii_bus *bus, int phy_addr, int regnum)

+{

+	unsigned long flags;

+	struct zx29_gmac_dev *prv = (struct zx29_gmac_dev*)bus->priv;

+	volatile unsigned 	*gmac	= (unsigned*)prv->base_addr;

+

+	unsigned val	= ( 1 << 0 					|		// busy λ

+					    0 << 1 					|		// R/W²Ù×÷ָʾλ

+					    PHY_CLOCK << 2)			|		// ʱÖÓλ

+					    (regnum & 0x1F) << 6	|		// ¼Ä´æÆ÷

+					    (phy_addr & 0x1F) << 11;		// ÎïÀíоƬ

+

+	spin_lock_irqsave(&prv->lock,flags);

+	while(mac_mii_is_busy());

+	MAC(0x0010) 	= val;

+	spin_unlock_irqrestore(&prv->lock,flags);

+

+	while(mac_mii_is_busy());

+

+	return (MAC(0x0014) & 0xFFFF);

+}

+

+static int zx29mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 value)

+{

+	struct zx29_gmac_dev *prv = (struct zx29_gmac_dev*)bus->priv;

+	volatile unsigned 	*gmac	= (unsigned*)prv->base_addr;

+

+	unsigned data	= ( 1 << 0 					|		// busy λ

+					    1 << 1 					|		// R/W²Ù×÷ָʾλ

+					    PHY_CLOCK << 2)			|		// ʱÖÓλ

+					    (regnum & 0x1F) << 6	|		// ¼Ä´æÆ÷

+					    (phy_addr & 0x1F) << 11;		// ÎïÀíоƬ

+

+	spin_lock_irq(&prv->lock);

+

+	while(mac_mii_is_busy());

+	MAC(0x0014)		= value;

+	MAC(0x0010)		= data;

+

+	spin_unlock_irq(&prv->lock);

+

+	while(mac_mii_is_busy());

+

+	return 0;

+}

+static int zx29mii_reset(struct mii_bus *bus)

+{

+	struct zx29_gmac_dev *priv = bus->priv;

+	volatile unsigned *gmac = (unsigned*)priv->base_addr;

+	gmac_start(priv->base_addr);

+	while(mac_mii_is_busy());

+	return 0;

+}

+

+static inline void zx29_gmac_set_macaddr(struct net_device* ndev)

+{

+    // È¡µÃMAC µØÖ·: 

+    // ²éÕÒMAC¼Ä´æÆ÷ÖеĵØÖ·£¬Èç¹ûÓÐЧ£¬Ê¹ÓøÃMAC£¬

+    // ÎÞЧÔòËæ»úÉú³É//zx297520v2   Ö±½ÓËæ»úÁËmac µØÖ·

+ 

+   int i =0;

+

+#if  MAC_ADDR_SET

+    for(i = 0;i<MAC_ADDR_LENTH;i++)

+    {

+     ndev->dev_addr[i]   = zx29_gmac_addr[i];

+    }

+

+    if(!is_valid_ether_addr(ndev->dev_addr))

+    {

+	    random_ether_addr(ndev->dev_addr);

+    }

+#else

+    random_ether_addr(ndev->dev_addr);

+#endif

+}

+

+

+static inline void zx29_gmac_linkisup(struct net_device *dev, int isup)

+{

+	struct zx29_gmac_dev *priv = netdev_priv(dev);

+	struct phy_device *phydev = priv->phydev;

+

+	priv->link.duplex = phydev->duplex;

+	priv->link.giga = (phydev->speed == 100);

+	if (priv->link.speed != phydev->speed) {

+		priv->link.speed = phydev->speed;

+		//zx29_gmac_set_rgmii_txclock(priv);

+	}

+	priv->link.isup = isup;

+	if (isup)

+		netif_carrier_on(dev);

+	phy_print_status(phydev);

+}

+

+static void zx29_gmac_stats_printk(struct net_device *dev)

+{

+	printk("dev->stats.rx_errors = %d.\n", dev->stats.rx_errors);

+	printk("dev->stats.rx_dropped = %d.\n", dev->stats.rx_dropped);

+	printk("dev->stats.rx_packets = %d.\n", dev->stats.rx_packets);

+	printk("dev->stats.tx_packets = %d.\n", dev->stats.tx_packets);

+}

+#if 0

+static void zx29_gmac_dump_reg(struct net_device *dev)

+{

+	volatile unsigned 	*gmac 	= (unsigned*)dev->base_addr;

+	u32 i;

+

+	printk("MAC:");

+	for(i=0;i<11;i++){

+		if(!(i%4)){printk("\n");}

+		printk("[%04x]:%04x",(0x1000+i*4),);

+	}

+	

+}

+#endif

+static void zx29_gmac_adjust_link(struct net_device *dev)

+{

+	struct zx29_gmac_dev *priv = netdev_priv(dev);

+	struct phy_device *phydev = priv->phydev;

+	volatile unsigned 	*gmac 	= (unsigned*)dev->base_addr;

+

+	//printk("@@@@@@@@@@zx29_gmac_adjust_link.\n");

+	//zx29_gmac_stats_printk(dev);

+	

+	if (priv->link.isup &&

+			(!phydev->link ||

+			(priv->link.speed != phydev->speed) ||

+			(priv->link.duplex != phydev->duplex))) {

+		priv->link.isup = 0;

+		netif_tx_disable(dev);

+		if (!phydev->link) {

+			netif_carrier_off(dev);

+			phy_print_status(phydev);

+			//gmac_event_notify(GMAC_ETH_PLUGOUT, NULL);

+		}

+	}

+

+	if (!priv->link.isup && phydev->link) {

+		if (priv->link.duplex != phydev->duplex) {

+			if (phydev->duplex)

+				mac_set_full_duplex_mode();

+			else

+				mac_set_half_duplex_mode();

+		}

+

+		if (priv->link.giga != (phydev->speed == 100)) {

+			if (phydev->speed == 100) 

+				mac_set_speed_100m_mode();

+			else 

+				mac_set_speed_10m_mode();

+		}

+

+		zx29_gmac_linkisup(dev, 1);

+		//gmac_event_notify(GMAC_ETH_PLUGIN, NULL);

+	}

+}

+

+static inline int zx29_gmac_phy_start(struct net_device *dev)

+{

+	struct zx29_gmac_dev *priv = netdev_priv(dev);

+	int i = 0;

+	struct phy_device *p = NULL;

+	int ret= 0;

+

+	if(priv->nports == 1) {

+		p = phy_find_first(priv->mii.bus);

+ 	} else {

+ 		if(priv->rmii_port < PHY_MAX_ADDR)

+			p = priv->mii.bus->phy_map[priv->rmii_port];

+	}

+

+	if(!p) {

+		printk("%s: no PHY found\n", dev->name);

+		return -ENODEV;

+	}

+

+	ret = phy_connect_direct(dev, p, &zx29_gmac_adjust_link, 0,

+			PHY_INTERFACE_MODE_RMII);

+

+	if (ret) {

+		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
+		return ret;

+	}

+	p->supported &= PHY_BASIC_FEATURES;

+	p->advertising = p->supported;

+	priv->phydev = p;

+	return 0;

+}

+

+static int zx29_gmac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)

+{

+    struct zx29_gmac_dev* prv = (struct zx29_gmac_dev*)netdev_priv(dev);

+    int ret = 0;

+

+    spin_lock_irq(&prv->lock);

+    cmd->advertising = prv->set_duplex_mode;

+    cmd->autoneg = prv->autoneg;

+    spin_unlock_irq(&prv->lock);

+

+    return ret;

+}

+

+static int zx29_gmac_do_settings(struct net_device *dev, struct ethtool_cmd *cmd)

+{

+	u32 speed = ethtool_cmd_speed(cmd);

+	struct zx29_gmac_dev* prv = (struct zx29_gmac_dev*)netdev_priv(dev);

+

+	spin_lock_irq(&prv->lock);

+	if(cmd->advertising == prv->set_duplex_mode)

+	{

+		spin_unlock_irq(&prv->lock);

+		return 0;

+	}

+	spin_unlock_irq(&prv->lock);

+

+	//verify the setting we care about

+	if(cmd->autoneg == AUTONEG_DISABLE &&

+	((speed != SPEED_100 &&

+	speed != SPEED_10) ||

+	(cmd->duplex != DUPLEX_HALF &&

+	cmd->duplex != DUPLEX_FULL)))

+	return -EINVAL;

+

+	prv->set_duplex_mode = cmd->advertising;

+	prv->autoneg = prv->phydev->autoneg = cmd->autoneg;

+	prv->phydev->speed = speed;

+	prv->phydev->duplex = cmd->duplex;

+	return genphy_config_aneg(prv->phydev);

+}

+

+

+static u32 zx29_gmac_get_link(struct net_device *dev)

+{

+	struct zx29_gmac_dev* prv = (struct zx29_gmac_dev*)netdev_priv(dev);

+

+	return prv->link.isup;

+}

+

+// ½ÓÊÕº¯Êý

+static int zx29_gmac_rx(struct net_device *dev)

+{

+	struct bd_rx 	*rx;

+	struct sk_buff	*skb;

+	struct sk_buff	*skb_new;

+	unsigned		len;

+	int   exhausted = 0;

+

+	struct zx29_gmac_dev* prv = (struct zx29_gmac_dev*)netdev_priv(dev);

+

+    rx  = get_rx_bd(dev);

+

+    if(unlikely(!rx))	goto rcv_done;

+

+    while(rx)

+    {

+        if((rx->RDES0 & ERR_RX_ES) || (rx->RDES0 & ERR_RX_LE))

+        {

+            dev->stats.rx_errors++;

+            if(rx->RDES0 & ERR_RX_LE)	dev->stats.rx_length_errors++;

+            if(rx->RDES0 & ERR_RX_OE)	dev->stats.rx_over_errors++;

+            if(rx->RDES0 & ERR_RX_IPC)	dev->stats.rx_frame_errors++;

+            if(rx->RDES0 & ERR_RX_LC)	dev->stats.rx_fifo_errors++;

+            if(rx->RDES0 & ERR_RX_CE)	dev->stats.rx_crc_errors++;

+        }

+        else

+        {

+            // ¶Ô½ÓÊÕÊý¾Ý½øÐд¦Àí

+            // ½«»·»ØÁ´±íÖеÄskbÈ¡³ö£¬²¢½«Ð·ÖÅäÐÂskb¹ÒÉÏ£¬ÓÃÓÚ½ÓÊÕÊý¾Ý

+            // ´ËʱËùÓÐÊý¾ÝÒѾ­±£´æÔÚskb->dataÖÐÁË£¬µ«ÊÇÊý¾Ý³¤¶Èskb»¹²»ÖªµÀ£¬²¢ÇÒÊý¾Ý»¹Ã»ÓÐCACHEͬ²½

+            // ¶Ôskb½øÐÐÊý¾Ý³¤¶È¡¢Êý¾Ýͬ²½´¦Àí

+            // È»ºóÉϱ¨¸øÐ­ÒéÉϲã

+

+            len = ((rx->RDES0 >> 16) & 0x3FFF) - 4;

+            if(len  > (ETH_FRAME_LEN+8))  

+            {

+            //LOG_INFO("rx data length more than %d\n", ETH_FRAME_LEN);

+                dev->stats.rx_dropped++;

+                goto rx_bd_reset;

+            }

+

+            skb_new = netdev_alloc_skb(dev, GMAC_FRAME_LEN + NET_IP_ALIGN);

+            if(unlikely(!skb_new))

+            {

+                //LOG_DBG(3, "memory squeeze, dropping packet\n");

+                dev->stats.rx_dropped++;

+				exhausted++;

+            }

+            else

+            {	

+            	exhausted = 0;

+            	dev->stats.rx_packets++;

+				dev->stats.rx_bytes += len;

+				// Êý¾Ý¶Áȡͬ²½DMA buffer ¸üиøcpu

+				dma_sync_single_for_cpu(&dev->dev, rx->dma_buf, GMAC_FRAME_LEN, DMA_FROM_DEVICE);

+                skb				= rx->skb;

+                skb_put(skb, len);

+                skb->protocol 		= eth_type_trans(skb, dev);

+                netif_rx(skb);		

+				

+                skb_reserve(skb_new, NET_IP_ALIGN);

+                //rx->dma_buf    		= __virt_to_phys((unsigned)skb_new->data);

+                rx->dma_buf    		= virtaddr_to_phys((unsigned)skb_new->data);

+                rx->skb			= skb_new;

+				wmb();

+                // Êý¾Ý¶Áȡͬ²½¸øÉ豸

+				dma_sync_single_for_device(&dev->dev, rx->dma_buf, GMAC_FRAME_LEN, DMA_TO_DEVICE); //TODO

+            }

+        }

+        rx_bd_reset:

+        rx->RDES0 = rx->RDES0 | DMA_OWNER;

+        prv->rx_bd_offset++;

+        prv->rx_bd_offset %= GMAC_RX_BD_NUM;

+		wmb();

+		

+		if(exhausted >= 10)

+			break;

+	

+        gmac_trig_receive((void*)dev->base_addr);     //´¥·¢½ÓÊÕ£¬»ñÈ¡½ÓÊÕ´«ÊäÃèÊö·û

+        rx	= get_rx_bd(dev);

+    }

+

+    rcv_done:

+    gmac_trig_receive((void*)dev->base_addr);

+	

+	return (exhausted >= 10);

+}

+

+

+// ·¢ËÍÖжϴ¦Àíº¯Êý

+static void zx29_gmac_tx(struct net_device *dev)

+{

+    register unsigned status;

+    struct net_device_stats	s	= dev->stats;

+    struct bd_tx *tx 			= get_txed_bd(dev);

+

+    while(tx)

+    {

+        status	= tx->TDES0;

+

+        if(tx->TDES0 & ERR_TX_ES)

+        {

+            s.tx_errors++;

+            if(status & ERR_TX_LC)		s.tx_carrier_errors++;

+            if(status & ERR_TX_NC)		s.tx_carrier_errors++;

+            if(status & ERR_TX_EC)		s.tx_window_errors++;

+            if(status & ERR_TX_LATECOL)	s.tx_window_errors++;

+            if(status & ERR_TX_UF)		s.tx_aborted_errors++;

+            if(status & ERR_TX_ED)		s.tx_aborted_errors++;

+            if(status & ERR_TX_JT)		s.tx_fifo_errors++;

+            if(status & ERR_TX_FF)		s.tx_fifo_errors++;

+

+			printk("%s, status=0x%x, err_cnt=%ld\n", __FUNCTION__,status, s.tx_errors);

+            //LOG_DBG(3, "%s %ld\n", __FUNCTION__, s.tx_errors);

+        }

+	dev_kfree_skb_any( tx->skb);  //wl

+	tx->skb = NULL;

+	tx = get_txed_bd(dev);      

+    }

+

+   if(netif_queue_stopped(dev))

+  // if (netif_carrier_ok(dev))

+    {

+        netif_wake_queue(dev);    //ʹµÃÉϲãЭ¶¨¿ªÊ¼´«ËÍеÄ×ÊÁÏÏÂÀ´

+    }

+}

+

+#ifndef GMAC_NO_INT

+static irqreturn_t zx29_gmac_interrupt(int irq, void *dev_id)

+{

+	struct net_device* dev 		= (struct net_device*)dev_id;

+	struct zx29_gmac_dev* prv 	= (struct zx29_gmac_dev*)netdev_priv(dev);

+	volatile unsigned *gmac 	= (unsigned*)dev->base_addr;

+

+	prv->int_event				= MAC(0x1014);									// ¶ÁÈ¡ÖжÏÐÅÏ¢

+	MAC(0x1014)					= prv->int_event;								// Çå³ýÖжÏ

+

+	// ÏȽ«GMACÖÐ¶ÏÆÁ±Î£¬È»ºó½«Ö÷Òª´¦ÀíÁ÷³Ì·ÅÔÚÈíÖжÏÖÐÍê³É

+	// ÈíÖжÏÍê³Éºó£¬ÔÙ´ò¿ªGAMCÖжÏ

+

+	mac_int_disable();

+	tasklet_schedule(&prv->tasklet);

+

+	return IRQ_HANDLED;

+}

+void zx29_gmac_tasklet(unsigned long dev_id)

+{

+    struct net_device* dev 		= (struct net_device*)dev_id;

+    struct zx29_gmac_dev* prv 	= (struct zx29_gmac_dev*)netdev_priv(dev);

+    volatile unsigned *gmac 	= (unsigned*)dev->base_addr;

+

+    unsigned events				= prv->int_event;								// ¶ÁÈ¡ÖжÏÖб£´æµÄÖжϱê¼Ç

+

+    // ¶ÔGMACÖжϽøÐÐÊÂÎñ´¦Àí£¬Ö±µ½Ã»ÓÐÖжÏ(ÊÂÎñ)ÐèÒª´¦Àí

+    do

+    {

+        if(events & INT_ST_TX)

+        {

+            zx29_gmac_tx(dev); 

+        }                                                     

+        if(events & INT_ST_RX)	    

+        {

+            zx29_gmac_rx(dev);

+        }

+

+        events			= MAC(0x1014);

+        MAC(0x1014)		= events;

+

+    } while( events & (INT_ST_TX | INT_ST_RX));

+

+    // ´ËʱGMACµÄÖжÏÊǹرյģ¬ÐèÒªÔٴδò¿ª

+    mac_int_enable();															// ÔÊÐíGMACÔٴβúÉúÖжÏ

+}

+

+#else

+

+void zx29_gmac_tasklet(unsigned long dev_id)

+{

+    struct net_device* dev 		= (struct net_device*)dev_id;

+    struct zx29_gmac_dev* prv 	= (struct zx29_gmac_dev*)netdev_priv(dev);

+    volatile unsigned *gmac 	= (unsigned*)dev->base_addr;

+	int rx_result = 0;

+    unsigned events				= prv->int_event;								// ¶ÁÈ¡ÖжÏÖб£´æµÄÖжϱê¼Ç

+

+    // ¶ÔGMACÖжϽøÐÐÊÂÎñ´¦Àí£¬Ö±µ½Ã»ÓÐÖжÏ(ÊÂÎñ)ÐèÒª´¦Àí

+    do

+    {

+        if(events & INT_ST_TX)

+        {

+            zx29_gmac_tx(dev); 

+        }                                                     

+        if(events & INT_ST_RX)	    

+        {

+           rx_result = zx29_gmac_rx(dev);

+			if(rx_result)//this means skb is exhausted,so break task

+				break;

+        }

+

+        events			= MAC(0x1014);

+        MAC(0x1014)		= events;

+

+    } while( events & (INT_ST_TX | INT_ST_RX));

+

+    // ´ËʱGMACµÄÖжÏÊǹرյģ¬ÐèÒªÔٴδò¿ª

+   // mac_int_enable();															// ÔÊÐíGMACÔٴβúÉúÖжÏ

+}

+

+enum hrtimer_restart gmac_timer_callback(struct hrtimer *timer)

+{

+	unsigned long delay_in_us = GTIMER_INTERVAL;

+	ktime_t gmac_schdule_time;

+	

+	gmac_schdule_time = ktime_set(0, delay_in_us * 1000);

+	hrtimer_forward_now(timer, gmac_schdule_time);

+

+	//gmac_kick_thread();

+    tasklet_schedule(g_gmac_tasklet);

+    //gmac_kick_plug_thread();

+    //tasklet_schedule(&gmac_net_dev_prv->tasklet);

+	return HRTIMER_RESTART;

+}

+

+#endif

+

+static int zx29_gmac_start_xmit(struct sk_buff *skb, struct net_device *dev)

+{

+	unsigned long		flags;

+	unsigned			len;

+	struct sk_buff		*skb_old;

+	struct bd_tx		*tx;

+	struct zx29_gmac_dev*	prv = (struct zx29_gmac_dev*)netdev_priv(dev);

+	

+	if(0 == prv->link.isup)

+	{

+		/*for 616000599226,phy not link ,so free skb 

+			*/

+		dev_kfree_skb_any(skb);

+		//netif_stop_queue(dev);

+		printk("TSP zx29 gmac xmit  phy not link\n");	 

+		return NETDEV_TX_OK;

+	}

+	

+	// ÔÚÈ¡µÃÃèÊö·ûʱÐèÒª»¥³â²Ù×÷

+	spin_lock_irqsave(&prv->lock, flags);

+

+	if(prv->stopped)

+	{

+		spin_unlock_irqrestore(&prv->lock,flags);

+		dev_kfree_skb_any(skb);

+		

+		printk("zx_net_start_xmit when stopped\n");

+		

+		return NETDEV_TX_OK;

+	}

+

+	tx	= get_tx_bd(dev);

+

+	if(!tx)

+	{

+		spin_unlock_irqrestore(&prv->lock,flags);

+		dev_kfree_skb_any(skb);

+		return NETDEV_TX_OK;

+	}

+	prv->tx_bd_offset++;

+	prv->tx_bd_offset %= GMAC_TX_BD_NUM;

+	spin_unlock_irqrestore(&prv->lock, flags);

+

+	if(skb->len > ETH_FRAME_LEN + 4)	//LOG_INFO("tx length too big\n");

+	printk("TSP zx29 gmac start xmit len too long\n");

+

+	// È¡µÃÃèÊö·ûÉϹÒ×ŵÄSKB£¬È»ºó½«¸ÃSKBÏú»Ù(¸ÃSKBµÄÊý¾ÝÒÑ·¢ËÍ)

+	// ÔÙ½«ÐµÄSKB¹ÒÉÏÈ¥(°üÀ¨SKBµØÖ·£¬ÒÔ¼°skb->data¶ÎµÄÎïÀíµØÖ·£¬ÓÃÓÚGMAC·¢ËÍÊý¾ÝÖ®ÓÃ)

+	// ×¢ÒâÔÚ½«skb->data¶ÎµÄÊý¾Ý·¢ËÍËùÓÐȨ½»¸øGMAC֮ǰ£¬ÐèÒª¶Ôdata¶ÎµÄÊý¾Ý½øÐÐCACHEͬ²½´¦Àí

+	// ÒòΪskb->dataµÄÊý¾ÝÊÇcachedµÄ

+

+	//wl skb_old		 = tx->skb;

+	//flush_skbuf(skb);

+

+	skb= flush_skbuf(skb);

+	if(NULL == skb)

+		BUG_ON(1);	 

+	len 				= MIN(skb->len, GMAC_FRAME_LEN - NET_IP_ALIGN);

+	tx->TDES0		  |= (0x07 << 28);					// ÉèÖÃ״̬±ê¼ÇΪ֡µÄµÚÒ»¸öÊý¾Ý°ü£¬×îºóÒ»¸öÊý°ü£¬Íê³ÉºóÖжÏ(Ò»Ö¡Ò»¸öÊý¾Ý°ü)

+	//tx->dma_buf	 = __virt_to_phys((unsigned)skb->data);

+	tx->dma_buf  = virtaddr_to_phys((unsigned)skb->data);

+	tx->skb 	 = skb;

+

+	// Êý¾ÝдÈëͬ²½

+	// dma_sync_single_for_device(&dev->dev, tx->dma_buf, len, DMA_TO_DEVICE);

+	//wl dev_kfree_skb_any(skb_old);

+	  

+	tx->TDES1	 = len;

+	tx->TDES0	|= DMA_OWNER;

+

+	//prv->tx_bd_offset++;

+	//prv->tx_bd_offset %= GMAC_TX_BD_NUM;

+	wmb();

+	dev->stats.tx_bytes 		+= len;

+	dev->stats.tx_packets++;

+	dev->trans_start			= jiffies;

+

+	gmac_trig_transmit((void*)dev->base_addr);

+	

+	return NETDEV_TX_OK;

+}

+

+

+static void zx29_gmac_tx_timeout(struct net_device *dev)

+{

+	struct zx29_gmac_dev* prv	= (struct zx29_gmac_dev*)netdev_priv(dev);

+

+	genphy_update_link(prv->phydev);

+	prv->link.isup= prv->phydev->link;

+	

+	if(0 == prv->link.isup) {	

+		printk("TSP zx29 gmac net timeout phy not link\n");						// PHY δÁ¬½Ó

+		netif_stop_queue(dev);

+		netif_carrier_off(dev);

+	} else {

+		printk("TSP zx29 gmac net timeout phy linked\n"); 

+		gmac_trig_transmit(dev);

+		gmac_trig_receive(dev);

+

+		netif_carrier_on(dev);

+		netif_wake_queue(dev);

+		dev->trans_start		= jiffies;

+		dev->stats.tx_errors++;

+		dev->stats.tx_dropped++;

+	}

+}

+

+int zx29_gmac_open(struct net_device *dev)

+{

+	struct zx29_gmac_dev *prv = netdev_priv(dev);

+	unsigned long flags;

+	int ret;

+	int err = 0;

+#ifdef GMAC_NO_INT

+	unsigned long delay_in_us = GTIMER_INTERVAL;

+	ktime_t gmac_schdule_time;

+#endif

+

+	err = phy_read_status(prv->phydev);

+    if (err < 0)

+	    return err;

+		

+	spin_lock_irqsave(&prv->lock, flags);

+	prv->link.speed = 0;

+

+	zx29_gmac_linkisup(dev, prv->phydev->link);

+

+	ret	= gmac_hw_init(dev);

+

+	if(ret) {

+		spin_unlock_irqrestore(&prv->lock, flags);

+		return ret;

+	}

+	

+    netif_carrier_on(dev);

+	spin_unlock_irqrestore(&prv->lock, flags);

+	phy_start(prv->phydev);

+	netif_start_queue(dev);

+

+#ifdef GMAC_NO_INT

+	gmac_schdule_time = ktime_set(0, delay_in_us * 1000);

+	if(prv->timer)

+		hrtimer_start(prv->timer, gmac_schdule_time, HRTIMER_MODE_REL );

+#endif

+

+	prv->stopped = 0;

+

+	printk("TSP zx29 gmac net open\n");

+

+	return 0;

+}

+

+static int zx29_gmac_stop(struct net_device *dev)

+{

+	unsigned long flags = 0;

+	int ret = 0;

+	struct zx29_gmac_dev* prv = (struct zx29_gmac_dev*)netdev_priv(dev);

+	

+	spin_lock_irqsave(&prv->lock, flags);

+	

+#ifdef GMAC_NO_INT

+	ret = hrtimer_cancel(prv->timer);

+	if(ret < 0) {

+		BUG_ON(1);

+		spin_unlock_irqrestore(&prv->lock,flags);

+		return ret;

+	}

+#endif

+

+	prv->stopped = 1;

+	

+	netif_stop_queue(dev);

+	netif_carrier_off(dev);

+	phy_stop(prv->phydev);

+

+	gmac_hw_deinit(dev);

+

+	memset(&dev->stats, 0, sizeof(struct net_device_stats));

+	

+	spin_unlock_irqrestore(&prv->lock,flags);

+	printk("TSP zx29 gmac net stop\n");

+

+	return 0;

+}

+

+static int zx29_gmac_set_mac_address(struct net_device *dev, void *p)

+{

+    int ret = eth_mac_addr(dev, p);

+	

+    if(!ret) {

+		gmac_update_mac(dev);

+		printk(" zx29 gmac set mac addr ok\n");

+    }

+

+    return ret;

+}

+/*

+static struct net_device_stats *zx29_gmac_stats(struct net_device *dev)

+{

+

+}

+*/

+static int zx29_gmac_suspend(struct device *dev)

+{

+    struct platform_device *pdev	= to_platform_device(dev);

+    struct net_device 	*ndev		= platform_get_drvdata(pdev);

+

+    if(ndev) {

+    	if(netif_running(ndev)) {

+    		netif_device_detach(ndev);

+    		gmac_stop((void*)ndev->base_addr);

+    	}

+    }

+    return 0;

+}

+

+static int zx29_gmac_resume(struct device *dev)

+{

+    struct platform_device *pdev	= to_platform_device(dev);

+    struct net_device *ndev 		= platform_get_drvdata(pdev);

+

+    if(ndev) {

+    	if(netif_running(ndev)) {

+        	gmac_start((void*)ndev->base_addr);

+        	netif_device_attach(ndev);

+    	}

+    }

+    return 0;

+}

+

+static int zx29_gmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)

+{

+	struct zx29_gmac_dev *priv = netdev_priv(dev);

+	if (!(netif_running(dev)))

+		return -EINVAL;

+	if (!priv->phydev)

+		return -EINVAL;

+	return phy_mii_ioctl(priv->phydev, ifr, cmd);

+}

+

+static const struct ethtool_ops zx29_gmac_ethtool_ops = 

+{

+    .get_settings	= zx29_gmac_get_settings,

+    .set_settings	= zx29_gmac_do_settings,

+    .get_link		= zx29_gmac_get_link,

+};

+

+static const struct net_device_ops zx29_gmac_netdev_ops =

+{

+    .ndo_open               = zx29_gmac_open,

+    .ndo_stop               = zx29_gmac_stop,

+    .ndo_start_xmit         = zx29_gmac_start_xmit,

+    .ndo_tx_timeout         = zx29_gmac_tx_timeout,

+    .ndo_do_ioctl             =  zx29_gmac_ioctl,

+   // .ndo_set_multicast_list =  zx_set_multicast,

+    .ndo_change_mtu         = eth_change_mtu,

+    .ndo_validate_addr      = eth_validate_addr,

+    .ndo_set_mac_address    = zx29_gmac_set_mac_address,

+};

+

+static int __devinit zx29_gmac_probe(struct platform_device *pdev)

+{

+	struct zx29_gmac_dev *prv = NULL;

+	struct net_device* ndev = alloc_etherdev(sizeof(struct zx29_gmac_dev));

+	volatile unsigned	*gmac = NULL;

+	struct gmac_platform_data *pdata = dev_get_platdata(&pdev->dev);

+	int ret;

+	unsigned long i;

+	struct mii_bus *mb;

+    struct resource *iomem;

+

+	printk("#########zx29_gmac_probe begin.\n");

+

+	if (!ndev)

+		return -ENOMEM;

+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);

+	if(!iomem)

+		return -ENXIO;

+

+	ret = gpio_request(63, "phy_rst"); /* gpio 63 */

+	gpio_direction_output(63, 1);

+	mdelay(1);

+	ret = gpio_request(127, "gmac_power"); /* gpio 83/124 */

+	gpio_direction_output(127, 1);

+	mdelay(15);

+	gpio_direction_output(63, 0);

+	mdelay(10);

+	gpio_direction_output(63, 1);

+	mdelay(15);

+	ndev->base_addr = iomem->start;

+	if(!ndev->base_addr)

+		return -ENXIO;		

+#ifndef GMAC_NO_INT

+	ndev->irq = platform_get_irq(pdev, 0);

+#endif

+	ndev->netdev_ops = &zx29_gmac_netdev_ops;

+	ndev->ethtool_ops = &zx29_gmac_ethtool_ops;

+

+	gmac 	= (unsigned*)ndev->base_addr;

+

+    /*¹Ø±ÕGMACËùÓй¦ÄÜ*/

+    dma_disable();

+    mac_disable();

+    mac_int_disable();

+

+	prv = netdev_priv(ndev);

+	memset(prv, 0, sizeof(*prv));

+	spin_lock_init(&prv->lock);

+

+	wake_lock_init(&prv->wake_lock, WAKE_LOCK_SUSPEND, "gmac_pm");

+    wake_lock(&prv->wake_lock);

+

+	zx29_gmac_set_macaddr(ndev);

+

+#ifndef GMAC_NO_INT

+	ret = request_irq(ndev->irq, zx29_gmac_interrupt, 0, ndev->name, ndev);

+	if (ret) {

+		printk(KERN_ERR "irq request failed: %d\n", ndev->irq);

+		goto errirq;
+	}

+#endif

+

+	ret = register_netdev(ndev);

+	if (ret) {

+		printk(KERN_ERR "error registering device %s\n",

+			ndev->name);

+		goto errdev;
+	}

+

+	prv->nports = pdata->nports;

+	prv->rmii_port = pdata->rmii_port;

+	prv->base_addr = ndev->base_addr;

+

+	prv->netdev = ndev;

+

+	mb = mdiobus_alloc();

+	if (!mb) {
+		printk(KERN_ERR "error allocating mii bus\n");

+		goto errmii;
+	}
+	mb->name = "zx29_gmac_mii";

+	mb->read = zx29mii_read;

+	mb->write = zx29mii_write;

+	mb->reset = zx29mii_reset;

+	mb->priv = prv;

+	snprintf(mb->id, MII_BUS_ID_SIZE, "%s-%x", pdev->name, pdev->id);
+	mb->phy_mask = pdata->port_mask;

+	mb->irq = &prv->mii.irq[0];

+	for (i = 0; i < PHY_MAX_ADDR; i++) {
+		int n = platform_get_irq(pdev, i + 1);
+		if (n < 0)
+			n = PHY_POLL;
+		prv->mii.irq[i] = n;

+	}

+	gmac_set_clk();

+	gmac_phy_release();

+	mdelay(500);/*Îñ±ØÒªdelay£¬·ñÔò»á³öÏÖ¶ÁÈ¡PHY¼Ä´æÆ÷ʧ°ÜµÄÇé¿ö*/

+	

+	mdiobus_register(mb);/*ÀïÃæÓжÁÈ¡PHY IDµÄ²Ù×÷£¬ËùÒÔ֮ǰÐèÒªÊÍ·ÅPHYµÄ¸´Î»*/

+	prv->mii.bus = mb;

+	ret = zx29_gmac_phy_start(ndev);

+	if (ret) {

+		//BUG_ON(1);

+		goto errphystart;

+	}

+	

+	platform_set_drvdata(pdev, ndev);

+

+	tasklet_init(&prv->tasklet, zx29_gmac_tasklet, (unsigned long)ndev);

+	g_gmac_tasklet = &prv->tasklet;

+

+	prv->dma_rx_vir	= dma_alloc_coherent(NULL,

+						GMAC_BUF_LEN,

+						&prv->dma_rx_phy,

+						GFP_KERNEL);

+	if(prv->dma_rx_vir == NULL) {

+		BUG_ON(1);

+		goto errphystart;

+	}

+	prv->dma_rx_phy_init = prv->dma_rx_phy;

+	prv->dma_rx_vir_init = prv->dma_rx_vir;

+    prv->dma_tx_vir	= prv->dma_rx_vir + GMAC_RX_BUF_LEN;

+    prv->dma_tx_phy	= prv->dma_rx_phy + GMAC_RX_BUF_LEN;

+

+#ifdef GMAC_NO_INT

+	sema_init(&prv->sem, 0);

+

+	prv->timer = kzalloc(sizeof(struct hrtimer),GFP_KERNEL);

+	if(prv->timer == NULL){

+		BUG_ON(1);

+		goto errmalloc;

+	}

+    hrtimer_init(prv->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );

+

+    prv->timer->function = gmac_timer_callback;

+#endif

+

+	gmac_event_init();

+

+	g_gmac_dev = prv;

+

+	printk("#########zx29_gmac_probe end.\n");

+

+	return 0;

+errmalloc:

+	dma_free_coherent(NULL, GMAC_BUF_LEN, prv->dma_rx_vir, prv->dma_rx_phy);

+errphystart:

+	mdiobus_unregister(prv->mii.bus);

+	mdiobus_free(prv->mii.bus);

+errmii:
+	unregister_netdev(ndev);

+errdev:

+#ifndef GMAC_NO_INT

+	free_irq(ndev->irq, ndev);

+#endif

+errirq:
+	free_netdev(ndev);

+

+	printk("#########zx29_gmac_probe fail.\n");

+	return ret;

+}

+

+static int __devexit zx29_gmac_remove(struct platform_device *pdev)

+{

+	struct net_device* ndev = platform_get_drvdata(pdev);

+	volatile unsigned	*gmac = NULL;

+	if(ndev) {

+		struct zx29_gmac_dev *prv = netdev_priv(ndev);

+		gmac_hw_deinit(ndev);

+		mdiobus_unregister(prv->mii.bus);

+#ifndef GMAC_NO_INT

+		free_irq(ndev->irq, ndev);

+#endif

+

+		tasklet_disable(&prv->tasklet);

+    	tasklet_kill(&prv->tasklet);

+

+		if(prv->dma_rx_vir)

+			dma_free_coherent(NULL, GMAC_BUF_LEN, prv->dma_rx_vir, prv->dma_rx_phy);   //ÊÍ·Ådma»º³åÇø

+

+		wake_unlock(&prv->wake_lock);

+		wake_lock_destroy(&prv->wake_lock);

+

+		unregister_netdev(ndev);

+		free_netdev(ndev);

+		platform_set_drvdata(pdev, NULL);

+	}

+	return 0;

+}

+

+static struct dev_pm_ops zx29_gmac_pm_ops =

+{

+	.suspend    = zx29_gmac_suspend,

+	.resume     = zx29_gmac_resume,

+};

+

+static struct platform_driver zx29_gmac_driver = {

+	.probe     = zx29_gmac_probe,

+	.remove    = __devexit_p(zx29_gmac_remove),

+	.driver    = {

+		.name     = "zx29_gmac",

+		.owner    = THIS_MODULE,

+		.pm       = &zx29_gmac_pm_ops,

+	},

+};

+

+static int __init zx29_gmac_init(void)

+{

+	printk(KERN_INFO "ZX29 GMAC ethernet driver\n");

+	return platform_driver_register(&zx29_gmac_driver);

+}

+

+

+static void __exit zx29_gmac_exit(void)

+{

+	platform_driver_unregister(&zx29_gmac_driver);

+}

+

+module_init(zx29_gmac_init);

+module_exit(zx29_gmac_exit);

+

+MODULE_LICENSE("GPL");

+MODULE_DESCRIPTION("ZX29 on chip Ethernet driver");

+MODULE_AUTHOR("zhang dongdong <zhang.dongdong16@zte.com.cn>");

+

+

diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/Kconfig b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/Kconfig
new file mode 100755
index 0000000..dc72c51
--- /dev/null
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/Kconfig
@@ -0,0 +1,152 @@
+#
+# PHY Layer Configuration
+#
+
+menuconfig PHYLIB
+	tristate "PHY Device support and infrastructure"
+	depends on !S390
+	depends on NETDEVICES
+	help
+	  Ethernet controllers are usually attached to PHY
+	  devices.  This option provides infrastructure for
+	  managing PHY devices.
+
+if PHYLIB
+
+comment "MII PHY device drivers"
+
+config AMD_PHY
+	tristate "Drivers for the AMD PHYs"
+	---help---
+	  Currently supports the am79c874
+
+config MARVELL_PHY
+	tristate "Drivers for Marvell PHYs"
+	---help---
+	  Currently has a driver for the 88E1011S
+	
+config DAVICOM_PHY
+	tristate "Drivers for Davicom PHYs"
+	---help---
+	  Currently supports dm9161e and dm9131
+
+config QSEMI_PHY
+	tristate "Drivers for Quality Semiconductor PHYs"
+	---help---
+	  Currently supports the qs6612
+
+config LXT_PHY
+	tristate "Drivers for the Intel LXT PHYs"
+	---help---
+	  Currently supports the lxt970, lxt971
+
+config CICADA_PHY
+	tristate "Drivers for the Cicada PHYs"
+	---help---
+	  Currently supports the cis8204
+
+config VITESSE_PHY
+        tristate "Drivers for the Vitesse PHYs"
+        ---help---
+          Currently supports the vsc8244
+
+config SMSC_PHY
+	tristate "Drivers for SMSC PHYs"
+	---help---
+	  Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs
+
+config BROADCOM_PHY
+	tristate "Drivers for Broadcom PHYs"
+	---help---
+	  Currently supports the BCM5411, BCM5421, BCM5461, BCM5464, BCM5481
+	  and BCM5482 PHYs.
+
+config BCM63XX_PHY
+	tristate "Drivers for Broadcom 63xx SOCs internal PHY"
+	depends on BCM63XX
+	---help---
+	  Currently supports the 6348 and 6358 PHYs.
+
+config ICPLUS_PHY
+	tristate "Drivers for ICPlus PHYs"
+	---help---
+	  Currently supports the IP175C and IP1001 PHYs.
+
+config REALTEK_PHY
+	tristate "Drivers for Realtek PHYs"
+	---help---
+	  Supports the Realtek 821x PHY.
+
+config NATIONAL_PHY
+	tristate "Drivers for National Semiconductor PHYs"
+	---help---
+	  Currently supports the DP83865 PHY.
+
+config STE10XP
+	tristate "Driver for STMicroelectronics STe10Xp PHYs"
+	---help---
+	  This is the driver for the STe100p and STe101p PHYs.
+
+config LSI_ET1011C_PHY
+	tristate "Driver for LSI ET1011C PHY"
+	---help---
+	  Supports the LSI ET1011C PHY.
+
+config MICREL_PHY
+	tristate "Driver for Micrel PHYs"
+	---help---
+	  Supports the KSZ9021, VSC8201, KS8001 PHYs.
+
+config FIXED_PHY
+	bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
+	depends on PHYLIB=y
+	---help---
+	  Adds the platform "fixed" MDIO Bus to cover the boards that use
+	  PHYs that are not connected to the real MDIO bus.
+
+	  Currently tested with mpc866ads and mpc8349e-mitx.
+
+config JLSEMI_PHY
+	bool "Driver forJLSEMI PHYs"
+	depends on PHYLIB=y
+	---help---
+	  Adds JLSEMI
+
+config MDIO_BITBANG
+	tristate "Support for bitbanged MDIO buses"
+	help
+	  This module implements the MDIO bus protocol in software,
+	  for use by low level drivers that export the ability to
+	  drive the relevant pins.
+
+	  If in doubt, say N.
+
+config MDIO_GPIO
+	tristate "Support for GPIO lib-based bitbanged MDIO buses"
+	depends on MDIO_BITBANG && GENERIC_GPIO
+	---help---
+	  Supports GPIO lib-based MDIO busses.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called mdio-gpio.
+
+config MDIO_OCTEON
+	tristate "Support for MDIO buses on Octeon SOCs"
+	depends on  CPU_CAVIUM_OCTEON
+	default y
+	help
+
+	  This module provides a driver for the Octeon MDIO busses.
+	  It is required by the Octeon Ethernet device drivers.
+
+	  If in doubt, say Y.
+
+endif # PHYLIB
+
+config MICREL_KS8995MA
+	tristate "Micrel KS8995MA 5-ports 10/100 managed Ethernet switch"
+	depends on SPI
+
+source "drivers/net/phy/icplus/Kconfig"
+source "drivers/net/phy/realtek/Kconfig"
+
diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/Makefile b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/Makefile
new file mode 100755
index 0000000..fa3391b
--- /dev/null
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/Makefile
@@ -0,0 +1,30 @@
+# Makefile for Linux PHY drivers
+
+libphy-objs			:= phy.o phy_device.o mdio_bus.o
+
+obj-$(CONFIG_PHYLIB)		+= libphy.o
+obj-$(CONFIG_MARVELL_PHY)	+= marvell.o
+obj-$(CONFIG_DAVICOM_PHY)	+= davicom.o
+obj-$(CONFIG_CICADA_PHY)	+= cicada.o
+obj-$(CONFIG_LXT_PHY)		+= lxt.o
+obj-$(CONFIG_QSEMI_PHY)		+= qsemi.o
+obj-$(CONFIG_SMSC_PHY)		+= smsc.o
+obj-$(CONFIG_VITESSE_PHY)	+= vitesse.o
+obj-$(CONFIG_BROADCOM_PHY)	+= broadcom.o
+obj-$(CONFIG_BCM63XX_PHY)	+= bcm63xx.o
+obj-$(CONFIG_ICPLUS_PHY)	+= icplus/
+obj-$(CONFIG_REALTEK_PHY)	+= realtek/
+obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
+obj-$(CONFIG_FIXED_PHY)		+= fixed.o
+obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
+obj-$(CONFIG_MDIO_GPIO)		+= mdio-gpio.o
+obj-$(CONFIG_NATIONAL_PHY)	+= national.o
+obj-$(CONFIG_DP83640_PHY)	+= dp83640.o
+obj-$(CONFIG_STE10XP)		+= ste10Xp.o
+obj-$(CONFIG_MICREL_PHY)	+= micrel.o
+obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
+obj-$(CONFIG_MICREL_KS8995MA)	+= spi_ks8995.o
+obj-$(CONFIG_AMD_PHY)		+= amd.o
+
+jlsemiphy-objs := jlsemi.o jlsemi-core.o
+obj-$(CONFIG_JLSEMI_PHY) += jlsemiphy.o
\ No newline at end of file
diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi-core.c b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi-core.c
new file mode 100755
index 0000000..51283db
--- /dev/null
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi-core.c
@@ -0,0 +1,2949 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 JLSemi Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "jlsemi-core.h"
+#include <linux/phy.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/netdevice.h>
+
+#define JL1XXX_PAGE24		24
+#define JL1XXX_LED_BLINK_REG	25
+
+#define JL1XXX_PAGE128		128
+#define JL1XXX_LED_GPIO_REG	29
+#define JL1XXX_WOL_CTRL_REG	28
+
+#define JL2XXX_PAGE3332		3332
+#define JL2XXX_LED_CTRL_REG	16
+#define JL2XXX_PAGE4096		4096
+#define JL2XXX_LED_BLINK_REG	20
+#define JL2XXX_LED_POLARITY_REG	19
+
+#define JL2XXX_PAGE128		128
+#define JL2XXX_FLD_CTRL_REG	28
+#define JL2XXX_FLD_EN		BIT(13)
+#define JL2XXX_FLD_MASK		0x1800
+#define JL2XXX_FLD_MASK_HEAD	11
+#define JL2XXX_FLD_DELAY_00MS	0
+#define JL2XXX_FLD_DELAY_10MS	1
+#define JL2XXX_FLD_DELAY_20MS	2
+#define JL2XXX_FLD_DELAY_40MS	3
+
+#define JL2XXX_SPEED10		0
+#define JL2XXX_SPEED100		1
+#define JL2XXX_SPEED1000	2
+
+#define JL2XXX_PHY_MODE_REG	30
+#define JL2XXX_FIBER_1000	BIT(12)
+#define JL2XXX_FIBER_100	BIT(11)
+#define JL2XXX_PHY_FIBER_MODE_MASK	0x1800
+#define JL2XXX_BMCR_DUPLEX	BIT(8)
+#define JL2XXX_LPA_FIBER_1000HALF	0x40
+#define JL2XXX_LPA_FIBER_1000FULL	0x20
+#define JL2XXX_BMCR_SPEED_LSB	BIT(13)
+#define JL2XXX_BMCR_SPEED_MSB	BIT(6)
+#define JL2XXX_BMCR_AN_RESTART	BIT(9)
+
+
+
+#define JL2XXX_SUPP_LED_MODE	(JL2XXX_LED0_LINK10 | \
+				 JL2XXX_LED0_LINK100 | \
+				 JL2XXX_LED0_LINK1000 | \
+				 JL2XXX_LED0_ACTIVITY | \
+				 JL2XXX_LED1_LINK10 | \
+				 JL2XXX_LED1_LINK100 | \
+				 JL2XXX_LED1_LINK1000 | \
+				 JL2XXX_LED1_ACTIVITY | \
+				 JL2XXX_LED2_LINK10 | \
+				 JL2XXX_LED2_LINK100 | \
+				 JL2XXX_LED2_LINK1000 | \
+				 JL2XXX_LED2_ACTIVITY)
+
+#define JL1XXX_SUPP_GPIO	(JL1XXX_GPIO_LED0_EN | \
+				 JL1XXX_GPIO_LED0_OUT | \
+				 JL1XXX_GPIO_LED1_EN | \
+				 JL1XXX_GPIO_LED1_OUT)
+
+#define JL1XXX_SUPP_LED_MODE	(JL1XXX_LED0_EEE | \
+				 JL1XXX_LED0_100_ACTIVITY | \
+				 JL1XXX_LED0_10_ACTIVITY | \
+				 JL1XXX_LED0_100_LINK | \
+				 JL1XXX_LED0_10_LINK | \
+				 JL1XXX_LED1_EEE | \
+				 JL1XXX_LED1_100_ACTIVITY | \
+				 JL1XXX_LED1_10_ACTIVITY | \
+				 JL1XXX_LED1_100_LINK | \
+				 JL1XXX_LED1_10_LINK)
+
+/************************* Configuration section *************************/
+
+
+/************************* JLSemi iteration code *************************/
+static int jl1xxx_led_static_op_set(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int err;
+
+	/* Enable LED operation */
+	jlsemi_set_bits(phydev, JL1XXX_PAGE7,
+			JL1XXX_LED_REG, JL1XXX_LED_EN);
+
+	/* Set led mode */
+	if (priv->led.enable & JL1XXX_LED_MODE_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL1XXX_PAGE129,
+					      JL1XXX_LED_MODE_REG,
+					      JL1XXX_SUPP_LED_MODE,
+					      priv->led.mode);
+		if (err < 0)
+			return err;
+	}
+	/* Set led period */
+	if (priv->led.enable & JL1XXX_LED_GLOABL_PERIOD_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL1XXX_PAGE24,
+					      JL1XXX_LED_BLINK_REG,
+					      LED_PERIOD_MASK,
+					      LEDPERIOD(
+					      priv->led.global_period));
+		if (err < 0)
+			return err;
+	}
+	/* Set led on time */
+	if (priv->led.enable & JL1XXX_LED_GLOBAL_ON_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL1XXX_PAGE24,
+					      JL1XXX_LED_BLINK_REG,
+					      LED_ON_MASK,
+					      LEDON(priv->led.global_on));
+		if (err < 0)
+			return err;
+	}
+	/*Set led gpio output */
+	if (priv->led.enable & JL1XXX_LED_GPIO_OUT_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL1XXX_PAGE128,
+					      JL1XXX_LED_GPIO_REG,
+					      JL1XXX_SUPP_GPIO,
+					      priv->led.gpio_output);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static int jl2xxx_led_static_op_set(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+
+	/* Set led mode */
+	if (priv->led.enable & JL2XXX_LED_MODE_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE3332,
+					      JL2XXX_LED_CTRL_REG,
+					      JL2XXX_SUPP_LED_MODE,
+					      priv->led.mode);
+		if (err < 0)
+			return err;
+	}
+	/* Set led period */
+	if (priv->led.enable & JL2XXX_LED_GLOABL_PERIOD_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE4096,
+					      JL2XXX_LED_BLINK_REG,
+					      LED_PERIOD_MASK,
+					      LEDPERIOD(
+					      priv->led.global_period));
+		if (err < 0)
+			return err;
+	}
+	/* Set led on time */
+	if (priv->led.enable & JL2XXX_LED_GLOBAL_ON_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE4096,
+					      JL2XXX_LED_BLINK_REG,
+					      LED_ON_MASK,
+					      LEDON(priv->led.global_on));
+		if (err < 0)
+			return err;
+	}
+	/* Set led polarity */
+	if (priv->led.enable & JL2XXX_LED_POLARITY_EN) {
+		err = jlsemi_set_bits(phydev, JL2XXX_PAGE4096,
+				      JL2XXX_LED_POLARITY_REG,
+				      priv->led.polarity);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+struct device *jlsemi_get_mdio(struct phy_device *phydev)
+{
+#if JLSEMI_DEV_COMPATIBLE
+	struct device *dev = &phydev->dev;
+#else
+	struct device *dev = &phydev->mdio.dev;
+#endif
+	return dev;
+}
+
+static struct device_node *get_device_node(struct phy_device *phydev)
+{
+	struct device *dev = jlsemi_get_mdio(phydev);
+
+	return dev->of_node;
+}
+
+static int jl1xxx_dts_led_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl1xxx,led-enable",
+			     &priv->led.enable);
+	of_property_read_u32(of_node, "jl1xxx,led-mode",
+			     &priv->led.mode);
+	of_property_read_u32(of_node, "jl1xxx,led-period",
+			     &priv->led.global_period);
+	of_property_read_u32(of_node, "jl1xxx,led-on",
+			     &priv->led.global_on);
+	of_property_read_u32(of_node, "jl1xxx,led-gpio",
+			     &priv->led.gpio_output);
+
+	return 0;
+}
+
+static int jl1xxx_dts_wol_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl1xxx,wol-enable",
+			     &priv->wol.enable);
+
+	return 0;
+}
+
+static int jl1xxx_dts_intr_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl1xxx,interrupt-enable",
+			     &priv->intr.enable);
+
+	return 0;
+}
+
+static int jl1xxx_dts_mdi_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl1xxx,mdi-enable",
+			     &priv->mdi.enable);
+	of_property_read_u32(of_node, "jl1xxx,mdi-rate",
+			     &priv->mdi.rate);
+	of_property_read_u32(of_node, "jl1xxx,mdi-amplitude",
+			     &priv->mdi.amplitude);
+
+	return 0;
+}
+
+static int jl1xxx_dts_rmii_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl1xxx,rmii-enable",
+			     &priv->rmii.enable);
+	of_property_read_u32(of_node, "jl1xxx,rmii-rx_timing",
+			     &priv->rmii.rx_timing);
+	of_property_read_u32(of_node, "jl1xxx,rmii-tx_timing",
+			     &priv->rmii.tx_timing);
+
+	return 0;
+}
+
+
+static int jl2xxx_dts_led_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,led-enable",
+			     &priv->led.enable);
+	of_property_read_u32(of_node, "jl2xxx,led-mode",
+			     &priv->led.mode);
+	of_property_read_u32(of_node, "jl2xxx,led-period",
+			     &priv->led.global_period);
+	of_property_read_u32(of_node, "jl2xxx,led-on",
+			     &priv->led.global_on);
+	of_property_read_u32(of_node, "jl2xxx,led-polarity",
+			     &priv->led.polarity);
+
+	return 0;
+}
+
+static int jl1xxx_c_macro_led_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+
+	/* Config LED */
+	struct jl_led_ctrl led_cfg = {
+		.enable		= JL1XXX_LED_CTRL_EN,
+		.mode		= JL1XXX_CFG_LED_MODE,
+		.global_period	= JL1XXX_GLOBAL_PERIOD_MS,
+		.global_on	= JL1XXX_GLOBAL_ON_MS,
+		.gpio_output	= JL1XXX_CFG_GPIO,
+	};
+
+	priv->led = led_cfg;
+
+	return 0;
+}
+
+static int jl1xxx_c_macro_wol_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+
+	struct jl_wol_ctrl wol_cfg = {
+		.enable		= JL1XXX_WOL_CTRL_EN,
+	};
+
+	priv->wol = wol_cfg;
+
+	return 0;
+}
+
+static int jl1xxx_c_macro_intr_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+
+	struct jl_intr_ctrl intr_cfg = {
+		.enable		= JL1XXX_INTR_CTRL_EN,
+	};
+
+	priv->intr = intr_cfg;
+
+	return 0;
+}
+
+static int jl1xxx_c_macro_mdi_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+
+	struct jl_mdi_ctrl mdi_cfg = {
+		.enable		= JL1XXX_MDI_CTRL_EN,
+		.rate		= JL1XXX_MDI_RATE,
+		.amplitude	= JL1XXX_MDI_AMPLITUDE,
+	};
+
+	priv->mdi = mdi_cfg;
+
+	return 0;
+}
+
+static int jl1xxx_c_macro_rmii_cfg_get(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+
+	struct jl_rmii_ctrl rmii_cfg = {
+		.enable		= JL1XXX_RMII_CTRL_EN,
+		.tx_timing	= JL1XXX_RMII_TX_TIMING,
+		.rx_timing	= JL1XXX_RMII_RX_TIMING,
+	};
+
+	priv->rmii = rmii_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_led_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_led_ctrl led_cfg = {
+		.enable		= JL2XXX_LED_CTRL_EN,
+		.mode		= JL2XXX_CFG_LED_MODE,
+		.global_period	= JL2XXX_GLOBAL_PERIOD_MS,
+		.global_on	= JL2XXX_GLOBAL_ON_MS,
+		.polarity	= JL2XXX_LED_POLARITY,
+	};
+
+	priv->led = led_cfg;
+
+	return 0;
+}
+
+static int jl1xxx_wol_operation_args(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct jl_wol_ctrl *wol = &priv->wol;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl1xxx_dts_wol_cfg_get(phydev);
+	else
+		jl1xxx_c_macro_wol_cfg_get(phydev);
+
+	/* Supported by default */
+	wol->ethtool = false;
+
+	return 0;
+}
+
+static int jl1xxx_intr_operation_args(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct jl_intr_ctrl *intr = &priv->intr;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl1xxx_dts_intr_cfg_get(phydev);
+	else
+		jl1xxx_c_macro_intr_cfg_get(phydev);
+
+	/* Not supported by default */
+	intr->ethtool = false;
+
+	return 0;
+}
+
+static int jl1xxx_mdi_operation_args(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct jl_mdi_ctrl *mdi = &priv->mdi;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl1xxx_dts_mdi_cfg_get(phydev);
+	else
+		jl1xxx_c_macro_mdi_cfg_get(phydev);
+
+	/* Not supported by default */
+	mdi->ethtool = false;
+
+	return 0;
+}
+
+static int jl1xxx_rmii_operation_args(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct jl_rmii_ctrl *rmii = &priv->rmii;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl1xxx_dts_rmii_cfg_get(phydev);
+	else
+		jl1xxx_c_macro_rmii_cfg_get(phydev);
+
+	/* Not supported by default */
+	rmii->ethtool = false;
+
+	return 0;
+}
+
+static int jl1xxx_led_operation_args(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	struct jl_led_ctrl *led = &priv->led;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl1xxx_dts_led_cfg_get(phydev);
+	else
+		jl1xxx_c_macro_led_cfg_get(phydev);
+
+	/* Not supported by default */
+	led->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_led_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_led_ctrl *led = &priv->led;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_led_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_led_cfg_get(phydev);
+
+	/* Not supported by default */
+	led->ethtool = false;
+
+	return 0;
+}
+
+
+static int jl2xxx_dts_fld_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,fld-enable",
+			     &priv->fld.enable);
+	of_property_read_u32(of_node, "jl2xxx,fld-delay",
+			     &priv->fld.delay);
+
+	return 0;
+}
+
+static int jl2xxx_dts_wol_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,wol-enable",
+			     &priv->wol.enable);
+
+	return 0;
+}
+
+static int jl2xxx_dts_intr_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,interrupt-enable",
+			     &priv->intr.enable);
+
+	return 0;
+}
+
+static int jl2xxx_dts_downshift_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,downshift-enable",
+			     &priv->downshift.enable);
+	of_property_read_u32(of_node, "jl2xxx,downshift-count",
+			     &priv->downshift.count);
+
+	return 0;
+}
+
+static int jl2xxx_dts_rgmii_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,rgmii-enable",
+			     &priv->rgmii.enable);
+	of_property_read_u32(of_node, "jl2xxx,rgmii-tx-delay",
+			     &priv->rgmii.tx_delay);
+	of_property_read_u32(of_node, "jl2xxx,rgmii-rx-delay",
+			     &priv->rgmii.rx_delay);
+
+	return 0;
+}
+
+static int jl2xxx_dts_patch_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,patch-enable",
+			     &priv->patch.enable);
+
+	return 0;
+}
+
+static int jl2xxx_dts_clk_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,clk-enable",
+			     &priv->clk.enable);
+
+	return 0;
+}
+
+static int jl2xxx_dts_work_mode_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,work_mode-enable",
+			     &priv->work_mode.enable);
+	of_property_read_u32(of_node, "jl2xxx,work_mode-mode",
+			     &priv->work_mode.mode);
+
+	return 0;
+}
+
+static int jl2xxx_dts_lpbk_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,lpbk-enable",
+			     &priv->lpbk.enable);
+	of_property_read_u32(of_node, "jl2xxx,lpbk-mode",
+			     &priv->lpbk.mode);
+
+	return 0;
+}
+
+static int jl2xxx_dts_slew_rate_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,slew_rate-enable",
+			     &priv->slew_rate.enable);
+
+	return 0;
+}
+
+static int jl2xxx_dts_rxc_out_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct device_node *of_node = get_device_node(phydev);
+
+	of_property_read_u32(of_node, "jl2xxx,rxc_out-enable",
+			     &priv->rxc_out.enable);
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_fld_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_fld_ctrl fld_cfg = {
+		.enable		= JL2XXX_FLD_CTRL_EN,
+		.delay		= JL2XXX_FLD_DELAY,
+	};
+
+	priv->fld = fld_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_wol_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_wol_ctrl wol_cfg = {
+		.enable		= JL2XXX_WOL_CTRL_EN,
+	};
+
+	priv->wol = wol_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_intr_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_intr_ctrl intr_cfg = {
+		.enable		= JL2XXX_INTR_CTRL_EN,
+	};
+
+	priv->intr = intr_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_downshift_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_downshift_ctrl downshift_cfg = {
+		.enable		= JL2XXX_DSFT_CTRL_EN,
+		.count		= JL2XXX_DSFT_AN_CNT,
+	};
+
+	priv->downshift = downshift_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_rgmii_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_rgmii_ctrl rgmii_cfg = {
+		.enable		= JL2XXX_RGMII_CTRL_EN,
+		.rx_delay	= JL2XXX_RGMII_RX_DLY_2NS,
+		.tx_delay	= JL2XXX_RGMII_TX_DLY_2NS,
+	};
+
+	priv->rgmii = rgmii_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_patch_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_patch_ctrl patch_cfg = {
+		.enable		= JL2XXX_PATCH_CTRL_EN,
+	};
+
+	priv->patch = patch_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_clk_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_clk_ctrl clk_cfg = {
+		.enable		= JL2XXX_CLK_CTRL_EN,
+	};
+
+	priv->clk = clk_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_work_mode_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_work_mode_ctrl work_mode_cfg = {
+		.enable		= JL2XXX_WORK_MODE_CTRL_EN,
+		.mode		= JL2XXX_WORK_MODE_MODE,
+	};
+
+	priv->work_mode = work_mode_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_lpbk_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_loopback_ctrl lpbk_cfg = {
+		.enable		= JL2XXX_LPBK_CTRL_EN,
+		.mode		= JL2XXX_LPBK_MODE,
+	};
+
+	priv->lpbk = lpbk_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_slew_rate_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_slew_rate_ctrl slew_rate_cfg = {
+		.enable		= JL2XXX_SLEW_RATE_CTRL_EN,
+	};
+
+	priv->slew_rate = slew_rate_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_c_macro_rxc_out_cfg_get(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	struct jl_rxc_out_ctrl rxc_out_cfg = {
+		.enable		= JL2XXX_RXC_OUT_CTRL_EN,
+	};
+
+	priv->rxc_out = rxc_out_cfg;
+
+	return 0;
+}
+
+static int jl2xxx_fld_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_fld_ctrl *fld = &priv->fld;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_fld_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_fld_cfg_get(phydev);
+
+	/* Supported by default */
+	fld->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_wol_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_wol_ctrl *wol = &priv->wol;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_wol_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_wol_cfg_get(phydev);
+
+	/* Supported by default */
+	wol->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_intr_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_intr_ctrl *intr = &priv->intr;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_intr_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_intr_cfg_get(phydev);
+
+	/* Not supported by default */
+	intr->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_downshift_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_downshift_ctrl *downshift = &priv->downshift;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_downshift_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_downshift_cfg_get(phydev);
+
+	/* Supported by default */
+	downshift->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_rgmii_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_rgmii_ctrl *rgmii = &priv->rgmii;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_rgmii_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_rgmii_cfg_get(phydev);
+
+	/* Not supported by default */
+	rgmii->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_patch_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_patch_ctrl *patch = &priv->patch;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_patch_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_patch_cfg_get(phydev);
+
+	/* Not supported by default */
+	patch->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_clk_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_clk_ctrl *clk = &priv->clk;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_clk_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_clk_cfg_get(phydev);
+
+	/* Not supported by default */
+	clk->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_work_mode_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_work_mode_ctrl *work_mode = &priv->work_mode;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_work_mode_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_work_mode_cfg_get(phydev);
+
+	/* Not supported by default */
+	work_mode->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_lpbk_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_loopback_ctrl *lpbk = &priv->lpbk;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_lpbk_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_lpbk_cfg_get(phydev);
+
+	/* Not supported by default */
+	lpbk->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_slew_rate_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_slew_rate_ctrl *slew_rate = &priv->slew_rate;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_slew_rate_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_slew_rate_cfg_get(phydev);
+
+	/* Not supported by default */
+	slew_rate->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_rxc_out_operation_args(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	struct jl_rxc_out_ctrl *rxc_out = &priv->rxc_out;
+
+	if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+		jl2xxx_dts_rxc_out_cfg_get(phydev);
+	else
+		jl2xxx_c_macro_rxc_out_cfg_get(phydev);
+
+	/* Not supported by default */
+	rxc_out->ethtool = false;
+
+	return 0;
+}
+
+static int jl2xxx_fld_static_op_set(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+	u8 val;
+
+	val = priv->fld.delay & 0xff;
+	err = jl2xxx_fld_dynamic_op_set(phydev, &val);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int jl1xxx_wol_cfg_rmii(struct phy_device *phydev)
+{
+	int err;
+	/* WOL Function should be in RMII Mode, the rmii
+	 * clock direction should be output
+	 */
+	err = jlsemi_modify_paged_reg(phydev, JL1XXX_PAGE7,
+				      JL1XXX_RMII_CTRL_REG,
+				      JL1XXX_RMII_OUT,
+				      JL1XXX_RMII_MODE);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int jl1xxx_wol_clear(struct phy_device *phydev)
+{
+	jlsemi_set_bits(phydev, JL1XXX_PAGE129,
+			JL1XXX_WOL_CTRL_REG, JL1XXX_WOL_CLEAR);
+
+	jlsemi_clear_bits(phydev, JL1XXX_PAGE129,
+			  JL1XXX_WOL_CTRL_REG, JL1XXX_WOL_CLEAR);
+
+	return 0;
+}
+
+static bool jl1xxx_wol_receive_check(struct phy_device *phydev)
+{
+	if (jlsemi_fetch_bit(phydev, JL1XXX_PAGE129,
+			     JL1XXX_WOL_CTRL_REG, JL1xxx_WOL_RECEIVE))
+		return true;
+	else
+		return false;
+
+}
+
+static int jl1xxx_wol_enable(struct phy_device *phydev, bool enable)
+{
+	if (enable)
+		jlsemi_clear_bits(phydev, JL1XXX_PAGE129,
+				  JL1XXX_WOL_CTRL_REG, JL1XXX_WOL_DIS);
+	else
+		jlsemi_set_bits(phydev, JL1XXX_PAGE129,
+				JL1XXX_WOL_CTRL_REG, JL1XXX_WOL_DIS);
+
+	return 0;
+}
+static int jl1xxx_wol_store_mac_addr(struct phy_device *phydev)
+{
+	int err;
+
+	jlsemi_write_page(phydev, JL1XXX_PAGE129);
+
+	/* Store the device address for the magic packet */
+	err = phy_write(phydev, JL1XXX_MAC_ADDR2_REG,
+			((ADDR8_HIGH_TO_LOW(
+			  phydev->attached_dev->dev_addr[0]) << 8) |
+			  ADDR8_HIGH_TO_LOW(
+			  phydev->attached_dev->dev_addr[1])));
+	if (err < 0)
+		return err;
+	err = phy_write(phydev, JL1XXX_MAC_ADDR1_REG,
+			((ADDR8_HIGH_TO_LOW(
+			  phydev->attached_dev->dev_addr[2]) << 8) |
+			  ADDR8_HIGH_TO_LOW(
+			  phydev->attached_dev->dev_addr[3])));
+	if (err < 0)
+		return err;
+	err = phy_write(phydev, JL1XXX_MAC_ADDR0_REG,
+			((ADDR8_HIGH_TO_LOW(
+			  phydev->attached_dev->dev_addr[4]) << 8) |
+			  ADDR8_HIGH_TO_LOW(
+			  phydev->attached_dev->dev_addr[5])));
+	if (err < 0)
+		return err;
+
+	/* change page to 0 */
+	jlsemi_write_page(phydev, JL1XXX_PAGE0);
+
+	return 0;
+}
+
+static int jl2xxx_wol_enable(struct phy_device *phydev, bool enable)
+{
+	if (enable) {
+		jlsemi_set_bits(phydev, JL2XXX_WOL_CTRL_PAGE,
+				JL2XXX_WOL_CTRL_REG, JL2XXX_WOL_GLB_EN);
+		jlsemi_clear_bits(phydev, JL2XXX_WOL_STAS_PAGE,
+				  JL2XXX_WOL_STAS_REG, JL2XXX_WOL_EN);
+	} else {
+		jlsemi_clear_bits(phydev, JL2XXX_WOL_CTRL_PAGE,
+				  JL2XXX_WOL_CTRL_REG, JL2XXX_WOL_GLB_EN);
+		jlsemi_set_bits(phydev, JL2XXX_WOL_STAS_PAGE,
+				JL2XXX_WOL_STAS_REG, JL2XXX_WOL_EN);
+	}
+	jlsemi_soft_reset(phydev);
+
+	return 0;
+}
+
+static int jl2xxx_wol_active_low_polarity(struct phy_device *phydev, bool low)
+{
+	if (low)
+		jlsemi_set_bits(phydev, JL2XXX_WOL_STAS_PAGE,
+				JL2XXX_WOL_STAS_REG, JL2XXX_WOL_POLARITY);
+	else
+		jlsemi_clear_bits(phydev, JL2XXX_WOL_STAS_PAGE,
+				  JL2XXX_WOL_STAS_REG, JL2XXX_WOL_POLARITY);
+
+	return 0;
+}
+
+static int jl2xxx_wol_clear(struct phy_device *phydev)
+{
+	jlsemi_set_bits(phydev, JL2XXX_WOL_STAS_PAGE,
+			JL2XXX_WOL_STAS_REG, JL2XXX_WOL_EVENT);
+	jlsemi_clear_bits(phydev, JL2XXX_WOL_STAS_PAGE,
+			  JL2XXX_WOL_STAS_REG, JL2XXX_WOL_EVENT);
+
+	return 0;
+}
+
+static int jl2xxx_store_mac_addr(struct phy_device *phydev)
+{
+	int err;
+
+	jlsemi_write_page(phydev, JL2XXX_WOL_STAS_PAGE);
+
+	/* Store the device address for the magic packet */
+	err = phy_write(phydev, JL2XXX_MAC_ADDR2_REG,
+			((phydev->attached_dev->dev_addr[0] << 8) |
+			  phydev->attached_dev->dev_addr[1]));
+	if (err < 0)
+		return err;
+	err = phy_write(phydev, JL2XXX_MAC_ADDR1_REG,
+			((phydev->attached_dev->dev_addr[2] << 8) |
+			  phydev->attached_dev->dev_addr[3]));
+	if (err < 0)
+		return err;
+	err = phy_write(phydev, JL2XXX_MAC_ADDR0_REG,
+			((phydev->attached_dev->dev_addr[4] << 8) |
+			  phydev->attached_dev->dev_addr[5]));
+	if (err < 0)
+		return err;
+
+	/* change page to 0 */
+	jlsemi_write_page(phydev, JL2XXX_PAGE0);
+
+	return 0;
+}
+
+/* Get fast link down for jl2xxx */
+#if (JL2XXX_PHY_TUNABLE)
+int jl2xxx_fld_dynamic_op_get(struct phy_device *phydev, u8 *msecs)
+{
+	int ret;
+	u16 val;
+
+	ret = jlsemi_read_paged(phydev, JL2XXX_PAGE128,
+				JL2XXX_FLD_CTRL_REG);
+
+	if (ret < 0)
+		return ret;
+
+	if (ret & JL2XXX_FLD_EN) {
+		*msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF;
+		return 0;
+	}
+
+	val = (ret & JL2XXX_FLD_MASK) >> JL2XXX_FLD_MASK_HEAD;
+
+	switch (val) {
+	case JL2XXX_FLD_DELAY_00MS:
+		*msecs = 0;
+		break;
+	case JL2XXX_FLD_DELAY_10MS:
+		*msecs = 10;
+		break;
+	case JL2XXX_FLD_DELAY_20MS:
+		*msecs = 20;
+		break;
+	case JL2XXX_FLD_DELAY_40MS:
+		*msecs = 40;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif
+/* Set fast link down for jl2xxx */
+int jl2xxx_fld_dynamic_op_set(struct phy_device *phydev, const u8 *msecs)
+{
+	u16 val;
+	int ret;
+
+#if (JL2XXX_PHY_TUNABLE)
+	if (*msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF)
+		return jlsemi_clear_bits(phydev, JL2XXX_PAGE128,
+					 JL2XXX_FLD_CTRL_REG,
+					 JL2XXX_FLD_EN);
+#endif
+	if (*msecs <= 5)
+		val = JL2XXX_FLD_DELAY_00MS;
+	else if (*msecs <= 15)
+		val = JL2XXX_FLD_DELAY_10MS;
+	else if (*msecs <= 30)
+		val = JL2XXX_FLD_DELAY_20MS;
+	else
+		val = JL2XXX_FLD_DELAY_40MS;
+
+	val = val << JL2XXX_FLD_MASK_HEAD;
+
+	ret = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE128,
+				      JL2XXX_FLD_CTRL_REG,
+				      JL2XXX_FLD_MASK, val);
+	if (ret < 0)
+		return ret;
+
+	ret = jlsemi_set_bits(phydev, JL2XXX_PAGE128,
+			      JL2XXX_FLD_CTRL_REG,
+			      JL2XXX_FLD_EN);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int jl2xxx_downshift_dynamic_op_get(struct phy_device *phydev, u8 *data)
+{
+	int val, cnt, enable;
+
+	val = jlsemi_read_paged(phydev, JL2XXX_PAGE0,
+				JL2XXX_DSFT_CTRL_REG);
+
+	if (val < 0)
+		return val;
+
+	enable = val & JL2XXX_DSFT_EN;
+	cnt = (val & JL2XXX_DSFT_AN_MASK) + 1;
+
+#if (JL2XXX_PHY_TUNABLE)
+	*data = enable ? cnt : DOWNSHIFT_DEV_DISABLE;
+#else
+	*data = enable ? cnt : 0;
+#endif
+	return 0;
+}
+
+int jl2xxx_downshift_dynamic_op_set(struct phy_device *phydev, u8 cnt)
+{
+	int val, err;
+
+	if (cnt > JL2XXX_DSFT_CNT_MAX)
+		return -E2BIG;
+
+	if (!cnt) {
+		err = jlsemi_clear_bits(phydev, JL2XXX_PAGE0,
+					JL2XXX_DSFT_CTRL_REG,
+					JL2XXX_DSFT_EN);
+	} else {
+		val = ((cnt - 1) & JL2XXX_DSFT_AN_MASK) | JL2XXX_DSFT_EN |
+			JL2XXX_DSFT_SMART_EN | JL2XXX_DSFT_AN_ERR_EN |
+			JL2XXX_DSFT_STL_CNT(18);
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE0,
+					      JL2XXX_DSFT_CTRL_REG,
+					      JL2XXX_DSFT_AN_MASK, val);
+	}
+
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl2xxx_downshift_static_op_set(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+
+	err = jl2xxx_downshift_dynamic_op_set(phydev,
+					      priv->downshift.count);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl2xxx_rgmii_static_op_set(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->rgmii.enable & JL2XXX_RGMII_TX_DLY_EN) {
+		err = jlsemi_set_bits(phydev, JL2XXX_PAGE3336,
+				      JL2XXX_RGMII_CTRL_REG,
+				      priv->rgmii.tx_delay);
+		if (err < 0)
+			return err;
+
+	} else {
+		err = jlsemi_clear_bits(phydev, JL2XXX_PAGE3336,
+					JL2XXX_RGMII_CTRL_REG,
+					priv->rgmii.tx_delay);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->rgmii.enable & JL2XXX_RGMII_RX_DLY_EN) {
+		err = jlsemi_set_bits(phydev, JL2XXX_PAGE3336,
+				      JL2XXX_RGMII_CTRL_REG,
+				      priv->rgmii.rx_delay);
+		if (err < 0)
+			return err;
+	} else {
+		err = jlsemi_clear_bits(phydev, JL2XXX_PAGE3336,
+				      JL2XXX_RGMII_CTRL_REG,
+				      priv->rgmii.rx_delay);
+		if (err < 0)
+			return err;
+	}
+
+	err = jlsemi_soft_reset(phydev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl2xxx_clk_static_op_set(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->clk.enable & JL2XXX_125M_CLK_OUT_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE2627,
+					      JL2XXX_CLK_CTRL_REG,
+					      JL2XXX_CLK_SSC_EN,
+					      JL2XXX_CLK_OUT_PIN |
+					      JL2XXX_CLK_125M_OUT |
+					      JL2XXXX_CLK_SRC);
+		if (err < 0)
+			return err;
+	} else if (priv->clk.enable & JL2XXX_25M_CLK_OUT_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE2627,
+					      JL2XXX_CLK_CTRL_REG,
+					      JL2XXX_CLK_SSC_EN |
+					      JL2XXX_CLK_125M_OUT,
+					      JL2XXX_CLK_OUT_PIN |
+					      JL2XXXX_CLK_SRC);
+		if (err < 0)
+			return err;
+	} else if (priv->clk.enable & JL2XXX_CLK_OUT_DIS) {
+		err = jlsemi_clear_bits(phydev, JL2XXX_PAGE2627,
+					JL2XXX_CLK_CTRL_REG,
+					JL2XXX_CLK_OUT_PIN);
+		if (err < 0)
+			return err;
+	}
+
+	err = jlsemi_soft_reset(phydev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl2xxx_slew_rate_static_op_set(struct phy_device *phydev)
+{
+	int err;
+
+	err = jlsemi_set_bits(phydev, JL2XXX_PAGE258,
+			      JL2XXX_SLEW_RATE_CTRL_REG,
+			      JL2XXX_SLEW_RATE_EN | JL2XXX_SLEW_RATE_REF_CLK |
+			      JL2XXX_SLEW_RATE_SEL_CLK);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl2xxx_rxc_out_static_op_set(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int mode;
+	int err;
+
+	/* fake power down */
+	err = jlsemi_set_bits(phydev, JL2XXX_PAGE18,
+			      JL2XXX_RXC_OUT_REG, JL2XXX_RXC_OUT);
+	if (err < 0)
+		return err;
+
+	mode = jlsemi_read_paged(phydev, JL2XXX_PAGE18, JL2XXX_WORK_MODE_REG);
+	/* Description: Some SOC Ethernet initialization requires PHY to
+	 * provide rx clock for MAC to pass initialization, otherwise DMA
+	 * initialization errors will be reported. However, when PHY is
+	 * set (MAC) sgmii<-->rgmii (PHY) mode, rx clock does not have a
+	 * clock.
+	 * Workaround: Configure PHY to utp<-->rgmii mode before Ethernet
+	 * initialization, and then configure it to sgmii<-->rgmii mode
+	 * after initialization is completed. The adverse effect is that
+	 * it will cause the link up time to become longer
+	 */
+	if (((priv->work_mode.enable & JL2XXX_WORK_MODE_STATIC_OP_EN) &&
+	   (priv->work_mode.mode == JL2XXX_MAC_SGMII_RGMII_MODE)) ||
+	   ((mode & JL2XXX_WORK_MODE_MASK) == JL2XXX_MAC_SGMII_RGMII_MODE)) {
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE18,
+					      JL2XXX_WORK_MODE_REG,
+					      JL2XXX_WORK_MODE_MASK,
+					      JL2XXX_UTP_RGMII_MODE);
+		if (err < 0)
+			return err;
+		/* Record the previous value */
+		priv->work_mode.mode = JL2XXX_MAC_SGMII_RGMII_MODE;
+		priv->rxc_out.inited = false;
+	}
+
+	err = jlsemi_soft_reset(phydev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl2xxx_work_mode_static_op_set(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+
+	jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE18,
+				JL2XXX_WORK_MODE_REG,
+				JL2XXX_WORK_MODE_MASK,
+				priv->work_mode.mode);
+
+	err = jlsemi_soft_reset(phydev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static inline int __genphy_setup_forced(struct phy_device *phydev)
+{
+	int err;
+	int ctl = 0;
+
+	phydev->pause = phydev->asym_pause = 0;
+
+	if (phydev->speed == SPEED_1000)
+		ctl |= BMCR_SPEED1000;
+	else if (phydev->speed == SPEED_100)
+		ctl |= BMCR_SPEED100;
+
+	if (phydev->duplex == DUPLEX_FULL)
+		ctl |= BMCR_FULLDPLX;
+
+	err = phy_write(phydev, MII_BMCR, ctl);
+
+	return err;
+}
+
+int jl2xxx_config_aneg_fiber(struct phy_device *phydev)
+{
+	if (phydev->autoneg != AUTONEG_ENABLE)
+		return __genphy_setup_forced(phydev);
+
+	/* Dou to fiber auto mode only support 1000M,
+	 * we set 1000M speed to reg0
+	 * NOTE: Do need restart AN otherwise will link down
+	 */
+	jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE0,
+				JL2XXX_BMCR_REG,
+				JL2XXX_BMCR_SPEED_LSB,
+				JL2XXX_BMCR_SPEED_MSB | BMCR_ANENABLE);
+	return 0;
+}
+
+static int jl2xxx_fiber_autoneg_config(struct phy_device *phydev)
+{
+	int speed;
+	int duplex;
+
+	speed = jlsemi_read_paged(phydev, JL2XXX_PAGE0, JL2XXX_PHY_MODE_REG);
+	if (speed < 0)
+		return speed;
+
+	duplex = jlsemi_fetch_bit(phydev, JL2XXX_PAGE0,
+				  MII_BMCR, JL2XXX_BMCR_DUPLEX);
+	if (duplex < 0)
+		return duplex;
+
+	if (duplex)
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	speed &= JL2XXX_PHY_FIBER_MODE_MASK;
+	switch (speed) {
+	case JL2XXX_FIBER_1000:
+		phydev->speed = SPEED_1000;
+		break;
+	case JL2XXX_FIBER_100:
+		phydev->speed = SPEED_100;
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int jl2xxx_update_fiber_status(struct phy_device *phydev)
+{
+	int status;
+	int link;
+
+	status = jlsemi_read_paged(phydev, JL2XXX_PAGE0, JL2XXX_PHY_MODE_REG);
+	if (status < 0)
+		return status;
+
+	link = status & JL2XXX_PHY_FIBER_MODE_MASK;
+
+	if (link)
+		phydev->link = 1;
+	else
+		phydev->link = 0;
+
+	if (phydev->autoneg == AUTONEG_ENABLE)
+		jl2xxx_fiber_autoneg_config(phydev);
+
+	return 0;
+}
+
+bool jl2xxx_read_fiber_status(struct phy_device *phydev)
+{
+	bool fiber_ok = false;
+	u16 phy_mode;
+	int val;
+
+	val = jlsemi_read_paged(phydev, JL2XXX_PAGE18, JL2XXX_WORK_MODE_REG);
+	phy_mode = val & JL2XXX_WORK_MODE_MASK;
+
+	if ((phydev->interface != PHY_INTERFACE_MODE_SGMII) &&
+	   ((phy_mode == JL2XXX_FIBER_RGMII_MODE) ||
+	    (phy_mode == JL2XXX_UTP_FIBER_RGMII_MODE))) {
+		jl2xxx_update_fiber_status(phydev);
+		if (phydev->link)
+			fiber_ok = true;
+	}
+
+	return fiber_ok;
+}
+
+static int jl2xxx_force_speed(struct phy_device *phydev, u16 speed)
+{
+	int err;
+
+	if (speed == JL2XXX_SPEED1000)
+		jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE0, MII_BMCR,
+					BMCR_SPEED100, BMCR_SPEED1000);
+	else if (speed == JL2XXX_SPEED100)
+		jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE0, MII_BMCR,
+					BMCR_SPEED1000, BMCR_SPEED100);
+	else if (speed == JL2XXX_SPEED10)
+		jlsemi_clear_bits(phydev, JL2XXX_PAGE0, MII_BMCR,
+				  BMCR_SPEED1000 | BMCR_SPEED100);
+
+	err = jlsemi_clear_bits(phydev, JL2XXX_PAGE0, MII_BMCR,
+				BMCR_ANENABLE);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int jl2xxx_lpbk_force_speed(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	if (priv->lpbk.mode == JL2XXX_LPBK_PCS_1000M)
+		jl2xxx_force_speed(phydev, JL2XXX_SPEED1000);
+	else if (priv->lpbk.mode == JL2XXX_LPBK_PCS_100M)
+		jl2xxx_force_speed(phydev, JL2XXX_SPEED100);
+	else if (priv->lpbk.mode == JL2XXX_LPBK_PCS_10M)
+		jl2xxx_force_speed(phydev, JL2XXX_SPEED10);
+
+	return 0;
+}
+
+int jl2xxx_lpbk_static_op_set(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+
+	if ((priv->lpbk.mode == JL2XXX_LPBK_PCS_10M) ||
+	    (priv->lpbk.mode == JL2XXX_LPBK_PCS_100M) ||
+	    (priv->lpbk.mode == JL2XXX_LPBK_PCS_1000M)) {
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE0,
+					      MII_BMCR, BMCR_LOOPBACK,
+					      BMCR_LOOPBACK);
+		if (err < 0)
+			return err;
+		err = jl2xxx_lpbk_force_speed(phydev);
+		if (err < 0)
+			return err;
+	} else if (priv->lpbk.mode == JL2XXX_LPBK_PMD_1000M) {
+		err = jlsemi_clear_bits(phydev, JL2XXX_PAGE160,
+					JL2XXX_REG25, JL2XXX_CPU_RESET);
+		if (err < 0)
+			return err;
+
+		jlsemi_write_page(phydev, JL2XXX_PAGE173);
+		phy_write(phydev, JL2XXX_REG16, JL2XXX_LOAD_GO);
+		phy_write(phydev, JL2XXX_REG17, JL2XXX_LOAD_DATA0);
+		jlsemi_write_page(phydev, JL2XXX_PAGE0);
+
+		err = jlsemi_set_bits(phydev, JL2XXX_PAGE160,
+				      JL2XXX_REG25, JL2XXX_CPU_RESET);
+		if (err < 0)
+			return err;
+
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE0,
+					      JL2XXX_REG20,
+					      JL2XXX_LPBK_MODE_MASK,
+					      JL2XXX_LPBK_PMD_MODE);
+		if (err < 0)
+			return err;
+
+		err = jlsemi_set_bits(phydev, JL2XXX_PAGE18, JL2XXX_REG21,
+				      JL2XXX_SPEED1000_NO_AN);
+		if (err < 0)
+			return err;
+
+		err = jlsemi_soft_reset(phydev);
+		if (err < 0)
+			return err;
+
+	} else if (priv->lpbk.mode == JL2XXX_LPBK_EXT_STUB_1000M) {
+		err = jlsemi_clear_bits(phydev, JL2XXX_PAGE160,
+					JL2XXX_REG25, JL2XXX_CPU_RESET);
+		if (err < 0)
+			return err;
+		jlsemi_write_page(phydev, JL2XXX_PAGE173);
+		phy_write(phydev, JL2XXX_REG16, JL2XXX_LOAD_GO);
+		phy_write(phydev, JL2XXX_REG17, JL2XXX_LOAD_DATA0);
+		jlsemi_write_page(phydev, JL2XXX_PAGE0);
+
+		err = jlsemi_set_bits(phydev, JL2XXX_PAGE160,
+				      JL2XXX_REG25, JL2XXX_CPU_RESET);
+		if (err < 0)
+			return err;
+
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE0,
+					      JL2XXX_REG20,
+					      JL2XXX_LPBK_MODE_MASK,
+					      JL2XXX_LPBK_EXT_MODE);
+		if (err < 0)
+			return err;
+
+		err = jlsemi_set_bits(phydev, JL2XXX_PAGE18, JL2XXX_REG21,
+				      JL2XXX_SPEED1000_NO_AN);
+		if (err < 0)
+			return err;
+
+		err = jlsemi_soft_reset(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+int jl1xxx_mdi_static_op_set(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->mdi.enable & JL1XXX_MDI_RATE_EN) {
+		err = jlsemi_set_bits(phydev, JL1XXX_PAGE24,
+				      JL1XXX_REG24, priv->mdi.rate);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->mdi.enable & JL1XXX_MDI_AMPLITUDE_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL1XXX_PAGE24,
+					      JL1XXX_REG24,
+					      JL1XXX_MDI_TX_BM_MASK,
+					      JL1XXX_MDI_TX_BM(
+					      priv->mdi.amplitude));
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+int jl1xxx_rmii_static_op_set(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->rmii.enable & JL1XXX_RMII_MODE_EN) {
+		err = jlsemi_set_bits(phydev, JL1XXX_PAGE7,
+				      JL1XXX_REG16, JL1XXX_RMII_MODE);
+		if (err < 0)
+			return err;
+	} else {
+		err = jlsemi_clear_bits(phydev, JL1XXX_PAGE7,
+					JL1XXX_REG16, JL1XXX_RMII_MODE);
+		if (err < 0)
+			return err;
+		return 0;
+	}
+
+	if (priv->rmii.enable & JL1XXX_RMII_CLK_50M_INPUT_EN) {
+		err = jlsemi_set_bits(phydev, JL1XXX_PAGE7,
+				      JL1XXX_REG16,
+				      JL1XXX_RMII_CLK_50M_INPUT);
+		if (err < 0)
+			return err;
+	} else {
+		err = jlsemi_clear_bits(phydev, JL1XXX_PAGE7,
+					JL1XXX_REG16,
+					JL1XXX_RMII_CLK_50M_INPUT);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->rmii.enable & JL1XXX_RMII_CRS_DV_EN) {
+		err = jlsemi_set_bits(phydev, JL1XXX_PAGE7,
+				      JL1XXX_REG16,
+				      JL1XXX_RMII_CRS_DV);
+		if (err < 0)
+			return err;
+	} else {
+		err = jlsemi_clear_bits(phydev, JL1XXX_PAGE7,
+					JL1XXX_REG16,
+					JL1XXX_RMII_CRS_DV);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->rmii.enable & JL1XXX_RMII_TX_SKEW_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL1XXX_PAGE7,
+					      JL1XXX_REG16,
+					      JL1XXX_RMII_TX_SKEW_MASK,
+					      JL1XXX_RMII_TX_SKEW(
+					      priv->rmii.tx_timing));
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->rmii.enable & JL1XXX_RMII_RX_SKEW_EN) {
+		err = jlsemi_modify_paged_reg(phydev, JL1XXX_PAGE7,
+					      JL1XXX_REG16,
+					      JL1XXX_RMII_RX_SKEW_MASK,
+					      JL1XXX_RMII_RX_SKEW(
+					      priv->rmii.rx_timing));
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static const u16 patch_fw_versions0[] = {0x9101, 0x9107};
+static const u16 patch_fw_versions1[] = {0x1101};
+static const u16 patch_fw_versions2[] = {0x930a};
+static const u16 patch_fw_versions3[] = {0x2208};
+
+#define patch_version0 0xdef2
+static const u32 init_data0[] = {
+	0x1f00a0, 0x1903f3, 0x1f0012, 0x150100, 0x1f00ad, 0x100000,
+	0x11e0c6, 0x1f00a0, 0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb,
+	0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb, 0x1f00ad, 0x110000,
+	0x120400, 0x130093, 0x140000, 0x150193, 0x160000, 0x170213,
+	0x180000, 0x12040c, 0x130293, 0x140000, 0x150313, 0x160000,
+	0x170393, 0x180000, 0x120418, 0x130413, 0x140000, 0x150493,
+	0x160000, 0x170513, 0x180000, 0x120424, 0x130593, 0x140000,
+	0x150613, 0x160000, 0x170693, 0x180000, 0x120430, 0x130713,
+	0x140000, 0x150793, 0x160000, 0x171137, 0x180000, 0x12043c,
+	0x13006f, 0x140060, 0x15a001, 0x160113, 0x17fd41, 0x18d026,
+	0x120448, 0x13d406, 0x14d222, 0x1517b7, 0x160800, 0x17aa23,
+	0x189407, 0x120454, 0x130713, 0x1430f0, 0x1567b7, 0x160800,
+	0x17a423, 0x1846e7, 0x120460, 0x13a703, 0x14a587, 0x156685,
+	0x168f55, 0x17ac23, 0x18a4e7, 0x12046c, 0x1367b9, 0x145737,
+	0x150800, 0x168793, 0x17ef27, 0x182023, 0x120478, 0x1374f7,
+	0x1407b7, 0x150800, 0x165bfc, 0x17d493, 0x180037, 0x120484,
+	0x13f493, 0x141f04, 0x15f793, 0x1607f7, 0x178fc5, 0x18c03e,
+	0x120490, 0x134702, 0x140793, 0x150210, 0x160763, 0x1700f7,
+	0x180793, 0x12049c, 0x130270, 0x140c63, 0x1530f7, 0x16a001,
+	0x1707b7, 0x180002, 0x1204a8, 0x138793, 0x146967, 0x15c83e,
+	0x1617b7, 0x170002, 0x188793, 0x1204b4, 0x13e567, 0x14c43e,
+	0x1537b7, 0x160002, 0x178793, 0x186867, 0x1204c0, 0x13c23e,
+	0x1447b7, 0x150002, 0x168793, 0x17e9a7, 0x1866b7, 0x1204cc,
+	0x130800, 0x14ca3e, 0x15a783, 0x166d86, 0x1775c1, 0x188713,
+	0x1204d8, 0x130ff5, 0x148ff9, 0x156735, 0x160713, 0x178007,
+	0x188fd9, 0x1204e4, 0x13ac23, 0x146cf6, 0x15a783, 0x1665c6,
+	0x175737, 0x180800, 0x1204f0, 0x136611, 0x14f793, 0x15f0f7,
+	0x16e793, 0x170807, 0x18ae23, 0x1204fc, 0x1364f6, 0x142783,
+	0x155c47, 0x169bf5, 0x172223, 0x185cf7, 0x120508, 0x13a703,
+	0x14f5c6, 0x158f51, 0x16ae23, 0x17f4e6, 0x180737, 0x120514,
+	0x130809, 0x14433c, 0x158fd1, 0x16c33c, 0x170637, 0x180800,
+	0x120520, 0x134a74, 0x14679d, 0x158793, 0x160e07, 0x179ae1,
+	0x18e693, 0x12052c, 0x130036, 0x14ca74, 0x154678, 0x1676e1,
+	0x178693, 0x185006, 0x120538, 0x138ff9, 0x148fd5, 0x1507c2,
+	0x168f6d, 0x1783c1, 0x188fd9, 0x120544, 0x13c67c, 0x140713,
+	0x151000, 0x160793, 0x170000, 0x189c23, 0x120550, 0x1324e7,
+	0x140713, 0x151010, 0x169123, 0x1726e7, 0x18470d, 0x12055c,
+	0x13c63a, 0x144702, 0x158d23, 0x162407, 0x17a223, 0x182607,
+	0x120568, 0x130793, 0x140270, 0x150413, 0x160000, 0x171463,
+	0x1800f7, 0x120574, 0x134789, 0x14c63e, 0x154709, 0x16cc3a,
+	0x174702, 0x180793, 0x120580, 0x130270, 0x141463, 0x1500f7,
+	0x16478d, 0x17cc3e, 0x180513, 0x12058c, 0x130000, 0x144792,
+	0x154581, 0x164485, 0x179782, 0x184018, 0x120598, 0x131775,
+	0x14e563, 0x1502e4, 0x162703, 0x170a04, 0x181163, 0x1205a4,
+	0x130297, 0x144818, 0x150563, 0x160097, 0x1747a2, 0x18c804,
+	0x1205b0, 0x139782, 0x1466b7, 0x150800, 0x16a703, 0x174c46,
+	0x189b71, 0x1205bc, 0x136713, 0x140027, 0x15a223, 0x164ce6,
+	0x174783, 0x180fd4, 0x1205c8, 0x13c7b9, 0x142683, 0x151004,
+	0x164745, 0x179763, 0x1820e6, 0x1205d4, 0x133737, 0x140822,
+	0x152683, 0x163007, 0x177645, 0x18167d, 0x1205e0, 0x138ef1,
+	0x142023, 0x1530d7, 0x162683, 0x172807, 0x18e693, 0x1205ec,
+	0x131006, 0x142023, 0x1528d7, 0x162683, 0x173807, 0x18e693,
+	0x1205f8, 0x131006, 0x142023, 0x1538d7, 0x162683, 0x174007,
+	0x18e693, 0x120604, 0x131006, 0x142023, 0x1540d7, 0x162683,
+	0x174807, 0x18e693, 0x120610, 0x131006, 0x142023, 0x1548d7,
+	0x1656b7, 0x170800, 0x18a703, 0x12061c, 0x133486, 0x14830d,
+	0x158b05, 0x16cf01, 0x17a703, 0x185c46, 0x120628, 0x137671,
+	0x14167d, 0x158f71, 0x166611, 0x17a223, 0x185ce6, 0x120634,
+	0x138f51, 0x14a223, 0x155ce6, 0x162703, 0x171084, 0x1846b2,
+	0x120640, 0x131c63, 0x1402d7, 0x153737, 0x160822, 0x172683,
+	0x182807, 0x12064c, 0x13e693, 0x140016, 0x152023, 0x1628d7,
+	0x172683, 0x183807, 0x120658, 0x13e693, 0x140016, 0x152023,
+	0x1638d7, 0x172683, 0x184007, 0x120664, 0x13e693, 0x140016,
+	0x152023, 0x1640d7, 0x172683, 0x184807, 0x120670, 0x13e693,
+	0x140016, 0x152023, 0x1648d7, 0x172703, 0x181004, 0x12067c,
+	0x1346b2, 0x149c63, 0x151ae6, 0x160737, 0x170800, 0x184b78,
+	0x120688, 0x130693, 0x140ff0, 0x15463d, 0x168b1d, 0x17ce3a,
+	0x1852b7, 0x120694, 0x130800, 0x144701, 0x154389, 0x16408d,
+	0x174311, 0x180537, 0x1206a0, 0x130820, 0x141593, 0x150077,
+	0x1695aa, 0x17418c, 0x184572, 0x1206ac, 0x1305c2, 0x1481c1,
+	0x1581a9, 0x167763, 0x1700b5, 0x189533, 0x1206b8, 0x1300e4,
+	0x144513, 0x15fff5, 0x168e69, 0x170537, 0x180800, 0x1206c4,
+	0x134568, 0x148121, 0x15893d, 0x167463, 0x1702b5, 0x18a583,
+	0x1206d0, 0x1306c2, 0x140763, 0x151277, 0x160a63, 0x171217,
+	0x1805c2, 0x1206dc, 0x1381c1, 0x14818d, 0x150d63, 0x161097,
+	0x178985, 0x180586, 0x1206e8, 0x1395b3, 0x1400b4, 0x15c593,
+	0x16fff5, 0x178eed, 0x180705, 0x1206f4, 0x1315e3, 0x14fa67,
+	0x1535b7, 0x160822, 0x17a703, 0x183005, 0x120700, 0x13757d,
+	0x148a3d, 0x150513, 0x160ff5, 0x178f69, 0x180622, 0x12070c,
+	0x138e59, 0x14a023, 0x1530c5, 0x168637, 0x170800, 0x185a38,
+	0x120718, 0x1375c1, 0x14f693, 0x150ff6, 0x168593, 0x170ff5,
+	0x188f6d, 0x120724, 0x1306a2, 0x148ed9, 0x15da34, 0x164682,
+	0x170713, 0x180210, 0x120730, 0x139163, 0x140ee6, 0x154711,
+	0x16e391, 0x17471d, 0x182023, 0x12073c, 0x1310e4, 0x142683,
+	0x150a04, 0x16471d, 0x179e63, 0x1800e6, 0x120748, 0x136737,
+	0x140800, 0x152703, 0x164cc7, 0x170693, 0x184000, 0x120754,
+	0x137713, 0x144807, 0x151463, 0x1600d7, 0x172223, 0x180e04,
+	0x120760, 0x134018, 0x141163, 0x150497, 0x165703, 0x1700c4,
+	0x181793, 0x12076c, 0x130117, 0x14db63, 0x150207, 0x168737,
+	0x170800, 0x184778, 0x120778, 0x137713, 0x140807, 0x15e705,
+	0x160513, 0x170000, 0x184792, 0x120784, 0x134581, 0x149782,
+	0x1547a2, 0x164711, 0x17c818, 0x18c004, 0x120790, 0x130d23,
+	0x140094, 0x150ca3, 0x160004, 0x179782, 0x1856b7, 0x12079c,
+	0x130800, 0x1442b8, 0x159b71, 0x16c2b8, 0x170513, 0x180000,
+	0x1207a8, 0x1347d2, 0x149782, 0x154703, 0x162684, 0x1703e3,
+	0x18de07, 0x1207b4, 0x13bbd9, 0x1407b7, 0x150002, 0x168793,
+	0x1765c7, 0x18c83e, 0x1207c0, 0x1327b7, 0x140002, 0x158793,
+	0x16dae7, 0x17c43e, 0x1847b7, 0x1207cc, 0x130002, 0x148793,
+	0x151427, 0x16c23e, 0x1757b7, 0x180002, 0x1207d8, 0x138793,
+	0x149867, 0x15b1fd, 0x162683, 0x171504, 0x184709, 0x1207e4,
+	0x1399e3, 0x14e2e6, 0x1536b7, 0x160822, 0x17a703, 0x183006,
+	0x1207f0, 0x13663d, 0x148f51, 0x15a023, 0x1630e6, 0x17bd39,
+	0x18c593, 0x1207fc, 0x130015, 0x14b5dd, 0x158991, 0x1635b3,
+	0x1700b0, 0x180589, 0x120808, 0x13bdf9, 0x148991, 0x15b593,
+	0x160015, 0x17bfdd, 0x180737, 0x120814, 0x130800, 0x144f28,
+	0x15cf89, 0x1647c2, 0x17893d, 0x189782, 0x120820, 0x1347e2,
+	0x140713, 0x151000, 0x162223, 0x1710e4, 0x182423, 0x12082c,
+	0x1310f4, 0x14474d, 0x15b729, 0x168111, 0x17b7dd, 0x1814e3,
+	0x120838, 0x13f097, 0x140737, 0x150800, 0x164770, 0x171713,
+	0x180106, 0x120844, 0x135d63, 0x140607, 0x1585b7, 0x160800,
+	0x17a683, 0x180d05, 0x120850, 0x1372c5, 0x147313, 0x1500f6,
+	0x1612fd, 0x17a703, 0x180d45, 0x12085c, 0x131513, 0x1400c3,
+	0x15f6b3, 0x160056, 0x178ec9, 0x18757d, 0x120868, 0x130393,
+	0x140ff5, 0x151293, 0x160083, 0x17f6b3, 0x180076, 0x120874,
+	0x139b41, 0x148211, 0x15e2b3, 0x160056, 0x171093, 0x180043,
+	0x120880, 0x137693, 0x140016, 0x156333, 0x160067, 0x170613,
+	0x187ff5, 0x12088c, 0x139713, 0x1400b6, 0x157633, 0x1600c3,
+	0x178e59, 0x189513, 0x120898, 0x1300a6, 0x147613, 0x159ff6,
+	0x169713, 0x170096, 0x188e49, 0x1208a4, 0x13f293, 0x14f0f2,
+	0x158e59, 0x16e2b3, 0x170012, 0x1806a2, 0x1208b0, 0x137613,
+	0x14eff6, 0x158e55, 0x16a823, 0x170c55, 0x18aa23, 0x1208bc,
+	0x130cc5, 0x1480e3, 0x15e807, 0x1646b7, 0x170822, 0x18a703,
+	0x1208c8, 0x13f006, 0x149b61, 0x156713, 0x160027, 0x17a023,
+	0x18f0e6, 0x1208d4, 0x13b5ad, 0x140000, 0x150000, 0x160000,
+	0x170000, 0x180000, 0x110000, 0x120400, 0x104000, 0x1f0000,
+};
+
+#define patch_version1 0x9f73
+static const u32 init_data1[] = {
+	0x1f00a0, 0x1903f3, 0x1f0012, 0x150100, 0x1f00ad, 0x100000,
+	0x11e0c6, 0x1f00a0, 0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb,
+	0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb, 0x1f00ad, 0x110000,
+	0x120400, 0x130093, 0x140000, 0x150193, 0x160000, 0x170213,
+	0x180000, 0x12040c, 0x130293, 0x140000, 0x150313, 0x160000,
+	0x170393, 0x180000, 0x120418, 0x130413, 0x140000, 0x150493,
+	0x160000, 0x170513, 0x180000, 0x120424, 0x130593, 0x140000,
+	0x150613, 0x160000, 0x170693, 0x180000, 0x120430, 0x130713,
+	0x140000, 0x150793, 0x160000, 0x171137, 0x180000, 0x12043c,
+	0x13006f, 0x140060, 0x15a001, 0x161111, 0x17cc06, 0x18ca22,
+	0x120448, 0x13c826, 0x1417b7, 0x150800, 0x16aa23, 0x179407,
+	0x180713, 0x120454, 0x1330f0, 0x1467b7, 0x150800, 0x16a423,
+	0x1746e7, 0x18a703, 0x120460, 0x13a587, 0x146685, 0x158f55,
+	0x16ac23, 0x17a4e7, 0x1867a9, 0x12046c, 0x135737, 0x140800,
+	0x158793, 0x16f737, 0x172023, 0x1874f7, 0x120478, 0x1307b7,
+	0x140800, 0x155bf8, 0x165793, 0x170037, 0x18f793, 0x120484,
+	0x131f07, 0x147713, 0x1507f7, 0x168fd9, 0x170713, 0x180210,
+	0x120490, 0x138763, 0x1400e7, 0x150713, 0x160270, 0x178263,
+	0x181ce7, 0x12049c, 0x13a001, 0x141437, 0x150002, 0x160793,
+	0x17e564, 0x18c43e, 0x1204a8, 0x1337b7, 0x140002, 0x158793,
+	0x166867, 0x17c23e, 0x1847b7, 0x1204b4, 0x130002, 0x148793,
+	0x15e9a7, 0x16c63e, 0x1767b7, 0x180800, 0x1204c0, 0x13a703,
+	0x146d87, 0x1576c1, 0x168693, 0x170ff6, 0x188f75, 0x1204cc,
+	0x1366b5, 0x148693, 0x158006, 0x168f55, 0x17ac23, 0x186ce7,
+	0x1204d8, 0x13a703, 0x1465c7, 0x1556b7, 0x160800, 0x177713,
+	0x18f0f7, 0x1204e4, 0x136713, 0x140807, 0x15ae23, 0x1664e7,
+	0x17a703, 0x185c46, 0x1204f0, 0x130413, 0x140000, 0x159b75,
+	0x16a223, 0x175ce6, 0x18a703, 0x1204fc, 0x13f5c7, 0x146691,
+	0x158f55, 0x16ae23, 0x17f4e7, 0x180737, 0x120508, 0x130809,
+	0x14433c, 0x158fd5, 0x16c33c, 0x170793, 0x180000, 0x120514,
+	0x130713, 0x141000, 0x159c23, 0x1624e7, 0x170713, 0x181010,
+	0x120520, 0x138d23, 0x142407, 0x159123, 0x1626e7, 0x17a223,
+	0x182607, 0x12052c, 0x13c026, 0x144782, 0x154581, 0x164485,
+	0x170513, 0x180000, 0x120538, 0x134792, 0x149782, 0x154018,
+	0x161775, 0x17e563, 0x1802e4, 0x120544, 0x132703, 0x140a04,
+	0x151163, 0x160297, 0x174818, 0x180563, 0x120550, 0x130097,
+	0x1447a2, 0x15c804, 0x169782, 0x176637, 0x180800, 0x12055c,
+	0x132703, 0x144c46, 0x159b71, 0x166713, 0x170027, 0x182223,
+	0x120568, 0x134ce6, 0x144703, 0x150fd4, 0x16c739, 0x172603,
+	0x181004, 0x120574, 0x134745, 0x141263, 0x1510e6, 0x163737,
+	0x170822, 0x182603, 0x120580, 0x133007, 0x1475c5, 0x1515fd,
+	0x168e6d, 0x172023, 0x1830c7, 0x12058c, 0x132603, 0x142807,
+	0x156613, 0x161006, 0x172023, 0x1828c7, 0x120598, 0x132603,
+	0x143807, 0x156613, 0x161006, 0x172023, 0x1838c7, 0x1205a4,
+	0x132603, 0x144007, 0x156613, 0x161006, 0x172023, 0x1840c7,
+	0x1205b0, 0x132603, 0x144807, 0x156613, 0x161006, 0x172023,
+	0x1848c7, 0x1205bc, 0x135637, 0x140800, 0x152703, 0x163486,
+	0x17830d, 0x188b05, 0x1205c8, 0x13cf01, 0x142703, 0x155c46,
+	0x1675f1, 0x1715fd, 0x188f6d, 0x1205d4, 0x136591, 0x142223,
+	0x155ce6, 0x168f4d, 0x172223, 0x185ce6, 0x1205e0, 0x132603,
+	0x140a04, 0x15471d, 0x161e63, 0x1700e6, 0x186737, 0x1205ec,
+	0x130800, 0x142703, 0x154cc7, 0x160613, 0x174000, 0x187713,
+	0x1205f8, 0x134807, 0x141463, 0x1500c7, 0x162223, 0x170e04,
+	0x184018, 0x120604, 0x131263, 0x140497, 0x155703, 0x1600c4,
+	0x171793, 0x180117, 0x120610, 0x13dc63, 0x140207, 0x158737,
+	0x160800, 0x174778, 0x187713, 0x12061c, 0x130807, 0x14e70d,
+	0x154782, 0x164581, 0x170513, 0x180000, 0x120628, 0x134792,
+	0x149782, 0x1547a2, 0x164711, 0x17c818, 0x18c004, 0x120634,
+	0x130d23, 0x140094, 0x150ca3, 0x160004, 0x179782, 0x185637,
+	0x120640, 0x130800, 0x144238, 0x159b71, 0x16c238, 0x174782,
+	0x180513, 0x12064c, 0x130000, 0x1447b2, 0x159782, 0x164703,
+	0x172684, 0x1803e3, 0x120658, 0x13ee07, 0x14bdd1, 0x152437,
+	0x160002, 0x170793, 0x18dae4, 0x120664, 0x13c43e, 0x1447b7,
+	0x150002, 0x168793, 0x171427, 0x18c23e, 0x120670, 0x1357b7,
+	0x140002, 0x158793, 0x169867, 0x17b589, 0x182603, 0x12067c,
+	0x131504, 0x144709, 0x151ee3, 0x16f2e6, 0x173637, 0x180822,
+	0x120688, 0x132703, 0x143006, 0x1565bd, 0x168f4d, 0x172023,
+	0x1830e6, 0x120694, 0x13b725, 0x140000, 0x150000, 0x160000,
+	0x170000, 0x180000, 0x110000, 0x120400, 0x104000, 0x1f0000,
+};
+
+#define patch_version2 0x2e9c
+static const u32 init_data2[] = {
+	0x1f00a0, 0x1903f3, 0x1f0012, 0x150100, 0x1f00ad, 0x100000,
+	0x11e0c6, 0x1f0102, 0x199000, 0x1f00a0, 0x1903fb, 0x1903fb,
+	0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb,
+	0x1f00ad, 0x110000, 0x121000, 0x13937c, 0x140120, 0x15675e,
+	0x16fca8, 0x1706b7, 0x180800, 0x12100c, 0x135af8, 0x145793,
+	0x150037, 0x16f793, 0x171f07, 0x187713, 0x121018, 0x1307f7,
+	0x148fd9, 0x150713, 0x1606a0, 0x179b63, 0x1808e7, 0x121024,
+	0x13cd19, 0x141121, 0x15c822, 0x16ca06, 0x17c626, 0x184789,
+	0x121030, 0x13842e, 0x140963, 0x152cf5, 0x1640d2, 0x174442,
+	0x1844b2, 0x12103c, 0x134501, 0x140161, 0x158082, 0x1617b7,
+	0x170800, 0x18aa23, 0x121048, 0x139407, 0x1467b7, 0x150800,
+	0x16a703, 0x17a587, 0x186605, 0x121054, 0x138f51, 0x14ac23,
+	0x15a4e7, 0x16670d, 0x170713, 0x18e9c7, 0x121060, 0x135637,
+	0x140800, 0x152023, 0x1674e6, 0x174ab8, 0x186713, 0x12106c,
+	0x130407, 0x14cab8, 0x15a703, 0x164d47, 0x1776fd, 0x188693,
+	0x121078, 0x1303f6, 0x148f75, 0x156713, 0x162807, 0x17aa23,
+	0x184ce7, 0x121084, 0x13a703, 0x147587, 0x157713, 0x16e1f7,
+	0x176713, 0x180607, 0x121090, 0x13ac23, 0x1474e7, 0x15a703,
+	0x164f47, 0x177713, 0x18f0f7, 0x12109c, 0x136713, 0x140107,
+	0x15aa23, 0x164ee7, 0x17a703, 0x18fc07, 0x1210a8, 0x139b5d,
+	0x14a023, 0x15fce7, 0x160713, 0x170300, 0x18a223, 0x1210b4,
+	0x13a6e7, 0x144501, 0x158082, 0x166489, 0x179023, 0x180004,
+	0x1210c0, 0x134505, 0x142ebd, 0x1557fd, 0x16c49c, 0x17c4dc,
+	0x184783, 0x1210cc, 0x130ec4, 0x149363, 0x152407, 0x16b795,
+	0x1787b7, 0x180800, 0x1210d8, 0x13a583, 0x140dc7, 0x15a783,
+	0x160e07, 0x178b91, 0x188063, 0x1210e4, 0x131807, 0x14d793,
+	0x150085, 0x1681b9, 0x178bbd, 0x188985, 0x1210f0, 0x1386b7,
+	0x140800, 0x15a703, 0x160d06, 0x17833e, 0x189513, 0x1210fc,
+	0x1300c7, 0x1477c5, 0x1517fd, 0x168f7d, 0x178f49, 0x18757d,
+	0x121108, 0x130293, 0x140ff5, 0x15a603, 0x160d46, 0x171793,
+	0x180083, 0x121114, 0x137733, 0x140057, 0x158f5d, 0x167713,
+	0x17f0f7, 0x181793, 0x121120, 0x130043, 0x148f5d, 0x157793,
+	0x16ff06, 0x170513, 0x187ff5, 0x12112c, 0x13e7b3, 0x140067,
+	0x159613, 0x1600b5, 0x178fe9, 0x188fd1, 0x121138, 0x139513,
+	0x1400a5, 0x15f793, 0x169ff7, 0x179613, 0x180095, 0x121144,
+	0x138fc9, 0x148fd1, 0x1505a2, 0x16f793, 0x17eff7, 0x188fcd,
+	0x121150, 0x13a823, 0x140ce6, 0x15aa23, 0x160cf6, 0x172783,
+	0x180f04, 0x12115c, 0x134719, 0x148563, 0x1500e7, 0x16472d,
+	0x179263, 0x1810e7, 0x121168, 0x130493, 0x141104, 0x154701,
+	0x164781, 0x17d683, 0x180104, 0x121174, 0x13e2b5, 0x1446a1,
+	0x154701, 0x16853e, 0x17c436, 0x18c23a, 0x121180, 0x13c03e,
+	0x142ca9, 0x1546a2, 0x164712, 0x174782, 0x1816fd, 0x12118c,
+	0x13972a, 0x14f6f5, 0x150637, 0x160820, 0x175693, 0x184037,
+	0x121198, 0x139713, 0x140077, 0x159732, 0x164310, 0x17d703,
+	0x180004, 0x1211a4, 0x139963, 0x1422e6, 0x159593, 0x160017,
+	0x176709, 0x18972e, 0x1211b0, 0x135703, 0x140087, 0x157e63,
+	0x1600e6, 0x17d703, 0x180184, 0x1211bc, 0x139023, 0x1400d4,
+	0x159693, 0x160017, 0x179423, 0x1800e4, 0x1211c8, 0x136709,
+	0x149736, 0x151423, 0x1600c7, 0x17d703, 0x180184, 0x1211d4,
+	0x133713, 0x140017, 0x150785, 0x164691, 0x170489, 0x1899e3,
+	0x1211e0, 0x13f8d7, 0x1447b5, 0x151f63, 0x161807, 0x176785,
+	0x1897a2, 0x1211ec, 0x13a703, 0x14a687, 0x154791, 0x160b63,
+	0x1718f7, 0x186489, 0x1211f8, 0x13d783, 0x140004, 0x159de3,
+	0x16e207, 0x172703, 0x180f04, 0x121204, 0x134789, 0x1418e3,
+	0x15e2f7, 0x164505, 0x172c15, 0x185637, 0x121210, 0x130800,
+	0x1446b7, 0x150822, 0x164238, 0x17a783, 0x18f806, 0x12121c,
+	0x133537, 0x140822, 0x1575c1, 0x16f793, 0x178ff7, 0x18e793,
+	0x121228, 0x133007, 0x14a023, 0x15f8f6, 0x162683, 0x173805,
+	0x188593, 0x121234, 0x130ff5, 0x14d793, 0x150086, 0x168b85,
+	0x17e793, 0x180767, 0x121240, 0x138eed, 0x1407a2, 0x158fd5,
+	0x162023, 0x1738f5, 0x187793, 0x12124c, 0x13ffd7, 0x14c23c,
+	0x15e793, 0x160027, 0x17c23c, 0x1847c1, 0x121258, 0x139023,
+	0x1400f4, 0x154501, 0x1622cd, 0x17bbd9, 0x184585, 0x121264,
+	0x134791, 0x14b569, 0x15476d, 0x169fe3, 0x17f6e7, 0x180737,
+	0x121270, 0x130002, 0x144481, 0x150713, 0x160a67, 0x178793,
+	0x184b84, 0x12127c, 0x130786, 0x1497a2, 0x15d683, 0x160ee7,
+	0x178526, 0x180485, 0x121288, 0x13e693, 0x140026, 0x159723,
+	0x160ed7, 0x179702, 0x180737, 0x121294, 0x130002, 0x144791,
+	0x150713, 0x160a67, 0x179ee3, 0x18fcf4, 0x1212a0, 0x130493,
+	0x141000, 0x154501, 0x1614fd, 0x172a15, 0x18fced, 0x1212ac,
+	0x134785, 0x148526, 0x15c03e, 0x16222d, 0x17470d, 0x184782,
+	0x1212b8, 0x135363, 0x1400a7, 0x154781, 0x160485, 0x174711,
+	0x1896e3, 0x1212c4, 0x13fee4, 0x14c38d, 0x156789, 0x164749,
+	0x179023, 0x1800e7, 0x1212d0, 0x1347c5, 0x142c23, 0x150ef4,
+	0x160793, 0x171000, 0x182a23, 0x1212dc, 0x130ef4, 0x1445d1,
+	0x150513, 0x160ec4, 0x172a15, 0x18b709, 0x1212e8, 0x136705,
+	0x149722, 0x155783, 0x16a5a7, 0x1746a1, 0x180785, 0x1212f4,
+	0x1307c2, 0x1483c1, 0x15f963, 0x1602f6, 0x171d23, 0x18a407,
+	0x121300, 0x132823, 0x140e04, 0x154783, 0x160ec4, 0x1789e3,
+	0x18da07, 0x12130c, 0x132783, 0x140f04, 0x1585e3, 0x16da07,
+	0x172783, 0x180f04, 0x121318, 0x138ee3, 0x14da07, 0x154741,
+	0x169de3, 0x17e2e7, 0x1847ed, 0x121324, 0x132823, 0x140ef4,
+	0x15bd05, 0x1606b7, 0x170002, 0x181d23, 0x121330, 0x13a4f7,
+	0x144481, 0x158693, 0x160a66, 0x178793, 0x184b84, 0x12133c,
+	0x130786, 0x1497a2, 0x15d703, 0x160ee7, 0x178526, 0x189b75,
+	0x121348, 0x139723, 0x140ee7, 0x159682, 0x160737, 0x170820,
+	0x189793, 0x121354, 0x130074, 0x140713, 0x152007, 0x1697ba,
+	0x17a023, 0x180007, 0x121360, 0x130737, 0x140002, 0x150485,
+	0x164791, 0x170693, 0x180a67, 0x12136c, 0x1396e3, 0x14fcf4,
+	0x150737, 0x160828, 0x172783, 0x184807, 0x121378, 0x13e793,
+	0x140207, 0x152023, 0x1648f7, 0x1747b9, 0x182823, 0x121384,
+	0x130ef4, 0x14b58d, 0x156709, 0x165683, 0x170007, 0x1847c9,
+	0x121390, 0x1393e3, 0x14e6f6, 0x1547b7, 0x160800, 0x17a783,
+	0x180c87, 0x12139c, 0x130693, 0x141000, 0x1507c2, 0x1683c1,
+	0x17f663, 0x1802f6, 0x1213a8, 0x135783, 0x140027, 0x150785,
+	0x1607c2, 0x1783c1, 0x181123, 0x1213b4, 0x1300f7, 0x144725,
+	0x157fe3, 0x16c6f7, 0x1766b7, 0x180800, 0x1213c0, 0x13a783,
+	0x14f5c6, 0x157779, 0x16177d, 0x178ff9, 0x18ae23, 0x1213cc,
+	0x13f4f6, 0x14b1a5, 0x151123, 0x160007, 0x17b18d, 0x18c1e3,
+	0x1213d8, 0x13dee6, 0x14bbdd, 0x150737, 0x160830, 0x172783,
+	0x181807, 0x1213e4, 0x132703, 0x142007, 0x154685, 0x160263,
+	0x1702d5, 0x18c763, 0x1213f0, 0x1300a6, 0x148bfd, 0x15c111,
+	0x164781, 0x17853e, 0x188082, 0x1213fc, 0x134689, 0x140b63,
+	0x1500d5, 0x16478d, 0x1719e3, 0x18fef5, 0x121408, 0x135793,
+	0x140047, 0x15a011, 0x168395, 0x178bfd, 0x18b7dd, 0x121414,
+	0x1383a9, 0x14bfed, 0x151141, 0x16c422, 0x17c606, 0x1847d1,
+	0x121420, 0x13842a, 0x149a63, 0x1500f5, 0x164508, 0x1707b7,
+	0x180002, 0x12142c, 0x13c02e, 0x148793, 0x156687, 0x169782,
+	0x174582, 0x18c04c, 0x121438, 0x1340b2, 0x144422, 0x150141,
+	0x168082, 0x17ed09, 0x184781, 0x121444, 0x134737, 0x140822,
+	0x152023, 0x16d0f7, 0x172023, 0x18d8f7, 0x121450, 0x132023,
+	0x14e0f7, 0x152023, 0x16e8f7, 0x178082, 0x186785, 0x12145c,
+	0x133737, 0x140822, 0x158693, 0x16fff7, 0x172023, 0x1830d7,
+	0x121468, 0x132023, 0x145007, 0x152023, 0x165807, 0x172023,
+	0x186007, 0x121474, 0x132023, 0x146807, 0x158793, 0x16c007,
+	0x17b7e1, 0x180000, 0x1f00a0, 0x1903f3, 0x1903fb, 0x1f0000,
+};
+
+/* no patch_version, val default=0 */
+static const u16 patch_version3;
+static const u32 init_data3[] = {
+	0x1f00a0, 0x1903f3, 0x1f0012, 0x150100, 0x1f00ad, 0x100000,
+	0x11e0c6, 0x1f00a0, 0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb,
+	0x1903fb, 0x1903fb, 0x1f0012, 0x150000, 0x1f00ad, 0x110000,
+	0x127c30, 0x138137, 0x140000, 0x15006f, 0x1600e0, 0x170000,
+	0x180000, 0x127c3c, 0x130000, 0x140000, 0x150000, 0x161161,
+	0x177601, 0x1895b7, 0x127c48, 0x13fffd, 0x146541, 0x1586b7,
+	0x160002, 0x17c222, 0x18c026, 0x127c54, 0x1307b7, 0x140002,
+	0x150613, 0x162b06, 0x178593, 0x183085, 0x127c60, 0x130293,
+	0x142900, 0x15157d, 0x168693, 0x1797c6, 0x188733, 0x127c6c,
+	0x1300b7, 0x148333, 0x1500c7, 0x16ec63, 0x1734e2, 0x184398,
+	0x127c78, 0x138f69, 0x140713, 0x152b07, 0x162023, 0x1700e3,
+	0x180791, 0x127c84, 0x1393e3, 0x14fed7, 0x1567a1, 0x16659d,
+	0x178793, 0x181377, 0x127c90, 0x132423, 0x142ef0, 0x158713,
+	0x166b75, 0x176785, 0x18ac23, 0x127c9c, 0x13eae7, 0x140737,
+	0x158693, 0x160713, 0x1770a7, 0x18ae23, 0x127ca8, 0x13eae7,
+	0x140737, 0x159737, 0x160713, 0x17a867, 0x18a023, 0x127cb4,
+	0x13ece7, 0x141737, 0x157737, 0x166789, 0x170713, 0x188f77,
+	0x127cc0, 0x13ae23, 0x140ce7, 0x150737, 0x16078a, 0x17a023,
+	0x180ee7, 0x127ccc, 0x130737, 0x14ffc7, 0x150713, 0x167137,
+	0x17a223, 0x180ee7, 0x127cd8, 0x133737, 0x147337, 0x150713,
+	0x162a37, 0x17ae23, 0x183ce7, 0x127ce4, 0x1302b7, 0x14050a,
+	0x150737, 0x160103, 0x17a023, 0x183e57, 0x127cf0, 0x130713,
+	0x143137, 0x15a223, 0x163ee7, 0x17668d, 0x188513, 0x127cfc,
+	0x137375, 0x1404b7, 0x150713, 0x16ae23, 0x17a0a6, 0x188313,
+	0x127d08, 0x1378a4, 0x1404b7, 0x1597ba, 0x16a023, 0x17a266,
+	0x188713, 0x127d14, 0x132474, 0x140437, 0x1577b7, 0x16a223,
+	0x17a2e6, 0x180313, 0x127d20, 0x130a74, 0x146711, 0x152c23,
+	0x16c667, 0x170337, 0x188793, 0x127d2c, 0x132e23, 0x14c667,
+	0x158293, 0x166072, 0x1703b7, 0x187737, 0x127d38, 0x132023,
+	0x14c857, 0x158393, 0x162a73, 0x172823, 0x18d077, 0x127d44,
+	0x1302b7, 0x141793, 0x150637, 0x160713, 0x172a23, 0x18d057,
+	0x127d50, 0x130613, 0x140256, 0x152c23, 0x16d0c7, 0x178493,
+	0x187474, 0x127d5c, 0x132e23, 0x14d097, 0x150413, 0x164a74,
+	0x172423, 0x18e087, 0x127d68, 0x131437, 0x14050a, 0x152623,
+	0x16e067, 0x170413, 0x188c74, 0x127d74, 0x132823, 0x14e087,
+	0x152023, 0x16ec77, 0x172223, 0x18ec57, 0x127d80, 0x1313b7,
+	0x1497ba, 0x152423, 0x16ecc7, 0x178413, 0x18a473, 0x127d8c,
+	0x132623, 0x14ec87, 0x158413, 0x167b75, 0x172223, 0x185287,
+	0x127d98, 0x138437, 0x140cc7, 0x150413, 0x167934, 0x172423,
+	0x185287, 0x127da4, 0x130437, 0x140e87, 0x152e23, 0x1676a7,
+	0x170413, 0x187134, 0x127db0, 0x132223, 0x147887, 0x1504b7,
+	0x160713, 0x176715, 0x182023, 0x127dbc, 0x13baa7, 0x148413,
+	0x1578a4, 0x162223, 0x17ba87, 0x188413, 0x127dc8, 0x131473,
+	0x142423, 0x15ba87, 0x160437, 0x1776b7, 0x180413, 0x127dd4,
+	0x130e64, 0x14c700, 0x150437, 0x16070a, 0x17c740, 0x188437,
+	0x127de0, 0x131306, 0x140413, 0x156934, 0x16cb00, 0x172a23,
+	0x1858a7, 0x127dec, 0x138413, 0x1478a4, 0x152c23, 0x165887,
+	0x178393, 0x185c73, 0x127df8, 0x132e23, 0x145877, 0x15a3b7,
+	0x167737, 0x178413, 0x186f73, 0x127e04, 0x132823, 0x145a87,
+	0x150437, 0x16078a, 0x172a23, 0x185a87, 0x127e10, 0x130437,
+	0x141707, 0x150413, 0x167134, 0x172c23, 0x185a87, 0x127e1c,
+	0x138393, 0x144f73, 0x152823, 0x165c77, 0x170437, 0x18078a,
+	0x127e28, 0x1303b7, 0x141847, 0x152a23, 0x165c87, 0x178393,
+	0x187133, 0x127e34, 0x132c23, 0x145c77, 0x1593b7, 0x167737,
+	0x178393, 0x186a73, 0x127e40, 0x132a23, 0x146a77, 0x152c23,
+	0x166a57, 0x1723b7, 0x1897ba, 0x127e4c, 0x132e23, 0x146ac7,
+	0x158413, 0x16a073, 0x172023, 0x186c87, 0x127e58, 0x131437,
+	0x1477b7, 0x156719, 0x160413, 0x174d74, 0x182623, 0x127e64,
+	0x138e87, 0x142437, 0x15068a, 0x162823, 0x178e67, 0x180413,
+	0x127e70, 0x13c874, 0x142a23, 0x158e87, 0x16c437, 0x177737,
+	0x180413, 0x127e7c, 0x136a74, 0x142c23, 0x15ba87, 0x162e23,
+	0x17ba57, 0x182023, 0x127e88, 0x13bcc7, 0x148613, 0x15dc73,
+	0x162223, 0x17bcc7, 0x18d348, 0x127e94, 0x138613, 0x1478a4,
+	0x15d710, 0x168393, 0x17f873, 0x182623, 0x127ea0, 0x130277,
+	0x14e737, 0x1577b7, 0x160713, 0x178e77, 0x18a423, 0x127eac,
+	0x13cce5, 0x142737, 0x15070a, 0x16a623, 0x17cc65, 0x180713,
+	0x127eb8, 0x130c77, 0x14a823, 0x15cce5, 0x16f737, 0x174510,
+	0x180713, 0x127ec4, 0x138e77, 0x14ac23, 0x1520e7, 0x164737,
+	0x173191, 0x180713, 0x127ed0, 0x135017, 0x14a223, 0x1524e7,
+	0x160737, 0x170200, 0x180713, 0x127edc, 0x137137, 0x14ae23,
+	0x15f6e7, 0x165737, 0x170713, 0x181761, 0x127ee8, 0x13a223,
+	0x14f8e7, 0x150737, 0x16cff8, 0x170713, 0x184007, 0x127ef4,
+	0x13a423, 0x14f8e7, 0x150737, 0x163fb0, 0x170713, 0x187137,
+	0x127f00, 0x13a623, 0x14f8e7, 0x151737, 0x160793, 0x170713,
+	0x188007, 0x127f0c, 0x13a823, 0x14f4e7, 0x151737, 0x16c37c,
+	0x17aa23, 0x18f4e7, 0x127f18, 0x136737, 0x14e793, 0x150713,
+	0x167a17, 0x17ac23, 0x18f4e7, 0x127f24, 0x131737, 0x14cb3c,
+	0x150713, 0x168077, 0x17ae23, 0x18f4e7, 0x127f30, 0x130737,
+	0x146080, 0x150713, 0x167937, 0x17a023, 0x18f6e7, 0x127f3c,
+	0x13d737, 0x148082, 0x150713, 0x16b7c7, 0x17a223, 0x18f6e7,
+	0x127f48, 0x136737, 0x140793, 0x150613, 0x164447, 0x17aa23,
+	0x184cc6, 0x127f54, 0x130637, 0x14a223, 0x150613, 0x162006,
+	0x17ac23, 0x184cc6, 0x127f60, 0x130713, 0x144f47, 0x15ae23,
+	0x164ce6, 0x174737, 0x18d0fc, 0x127f6c, 0x130713, 0x14fa07,
+	0x15a023, 0x164ee6, 0x178737, 0x189207, 0x127f78, 0x130713,
+	0x147937, 0x15a223, 0x16f2e7, 0x17c737, 0x1867a1, 0x127f84,
+	0x130713, 0x1437c7, 0x15a423, 0x16f2e7, 0x178737, 0x187807,
+	0x127f90, 0x130713, 0x147937, 0x15a623, 0x16f2e7, 0x17d737,
+	0x180793, 0x127f9c, 0x130713, 0x14b3c7, 0x15a823, 0x16f2e7,
+	0x176737, 0x18cb7c, 0x127fa8, 0x130713, 0x140807, 0x15aa23,
+	0x16f2e7, 0x178737, 0x188082, 0x127fb4, 0x130713, 0x140827,
+	0x15ac23, 0x16f2e7, 0x17806f, 0x18af4f, 0x127fc0, 0x134412,
+	0x144482, 0x154501, 0x160121, 0x178082, 0x184398, 0x127fcc,
+	0x13b94d, 0x140000, 0x150000, 0x160000, 0x170000, 0x180000,
+	0x110000, 0x127c30, 0x104000, 0x1f0000,
+};
+
+static bool jl2xxx_patch_check(struct phy_device *phydev,
+			      struct jl_patch *patch)
+{
+
+	bool patch_ok = false;
+	int val;
+	int i;
+
+	val = jlsemi_read_paged(phydev, JL2XXX_PAGE0, JL2XXX_PHY_INFO_REG);
+	for (i = 0; i < patch->phy.info_len; i++) {
+		if (val == patch->phy.info[i])
+			patch_ok |= true;
+	}
+
+	return patch_ok;
+}
+
+static bool jl2xxx_patch_sgmii_2_utp_check(struct phy_device *phydev,
+				   struct jl_patch *patch)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	bool patch_ok = false;
+	int mode;
+
+	mode = jlsemi_read_paged(phydev, JL2XXX_PAGE18, JL2XXX_WORK_MODE_REG);
+	/* Can only be used in sgmii->utp mode */
+	if (((priv->work_mode.enable & JL2XXX_WORK_MODE_STATIC_OP_EN) &&
+	   (priv->work_mode.mode == JL2XXX_UTP_SGMII_MODE)) ||
+	   ((mode & JL2XXX_WORK_MODE_MASK) == JL2XXX_UTP_SGMII_MODE)) {
+		patch_ok = jl2xxx_patch_check(phydev, patch);
+	}
+	return patch_ok;
+}
+
+static int jl2xxx_patch_load(struct phy_device *phydev,
+			     struct jl_patch *patch)
+{
+	int regaddr, val;
+	int i, j;
+
+	for (i = 0; i < patch->data_len; i++) {
+		regaddr = ((patch->data[i] >> 16) & 0xff);
+		val = (patch->data[i] & 0xffff);
+		phy_write(phydev, regaddr, val);
+		if (regaddr == 0x18) {
+			phy_write(phydev, 0x10, 0x8006);
+			for (j = 0; j < 8; j++) {
+				if (phy_read(phydev, 0x10) == 0)
+					break;
+			}
+		}
+	}
+	/* Wait load patch complete */
+	msleep(20);
+
+	return 0;
+}
+
+static int jl2xxx_patch_verify_by_version(struct phy_device *phydev,
+					  struct jl_patch *patch)
+{
+	int version;
+
+	version = jlsemi_read_paged(phydev, JL2XXX_PAGE174, JL2XXX_PATCH_REG);
+	if (version != patch->version)
+		JLSEMI_PHY_MSG(KERN_ERR
+			       "%s: patch version is not match\n", __func__);
+	return 0;
+}
+
+static int jl2xxx_patch_verify_by_regval(struct phy_device *phydev,
+					 struct jl_patch *patch)
+{
+	int val;
+
+	val = jlsemi_read_paged(phydev, JL2XXX_PAGE179, JL2XXX_REG16);
+	if (val != patch->version)
+		JLSEMI_PHY_MSG(KERN_ERR "%s: patch load failed!\n", __func__);
+	return 0;
+}
+
+static struct jl_patch phy_patches[] = {
+	{
+		.data = init_data0,
+		.data_len = ARRAY_SIZE(init_data0),
+		.version = patch_version0,
+		{
+			.info = patch_fw_versions0,
+			.info_len = ARRAY_SIZE(patch_fw_versions0),
+		},
+		.check = jl2xxx_patch_check,
+		.load = jl2xxx_patch_load,
+		.verify = jl2xxx_patch_verify_by_version,
+
+	},
+	{
+		.data = init_data1,
+		.data_len = ARRAY_SIZE(init_data1),
+		.version = patch_version1,
+		{
+			.info = patch_fw_versions1,
+			.info_len = ARRAY_SIZE(patch_fw_versions1),
+		},
+		.check = jl2xxx_patch_check,
+		.load = jl2xxx_patch_load,
+		.verify = jl2xxx_patch_verify_by_version,
+	},
+	{
+		.data = init_data2,
+		.data_len = ARRAY_SIZE(init_data2),
+		.version = patch_version2,
+		{
+			.info = patch_fw_versions2,
+			.info_len = ARRAY_SIZE(patch_fw_versions2),
+		},
+		.check = jl2xxx_patch_check,
+		.load = jl2xxx_patch_load,
+		.verify = jl2xxx_patch_verify_by_version,
+	},
+	{
+		.data = init_data3,
+		.data_len = ARRAY_SIZE(init_data3),
+		.version = 0,
+		{
+			.info = patch_fw_versions3,
+			.info_len = ARRAY_SIZE(patch_fw_versions3),
+		},
+		.check = jl2xxx_patch_sgmii_2_utp_check,
+		.load = jl2xxx_patch_load,
+		.verify = jl2xxx_patch_verify_by_regval,
+	},
+};
+
+int jl2xxx_patch_static_op_set(struct phy_device *phydev)
+{
+	int found;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(phy_patches); i++) {
+		found = jl2xxx_pre_init(phydev, &phy_patches[i]);
+		if (found)
+			return found;
+	}
+
+	return 0;
+}
+
+static int jl2xxx_patch_dynamic_op_set(struct phy_device *phydev)
+{
+	const u16 fw_version = 0x2208;
+	static u16 last_status;
+	u16 value, cur_status;
+
+	/* read page 0, reg 29 */
+	value = jlsemi_read_paged(phydev, JL2XXX_PAGE0, JL2XXX_PHY_INFO_REG);
+	if (value != fw_version)
+		return 0;
+
+	while (1) {
+		/* get page 181, reg 18, bit 2 */
+		value = jlsemi_read_paged(phydev, JL2XXX_PAGE181, JL2XXX_REG18);
+		cur_status = (value >> JL2XXX_SERDES_LINK) & 1;
+
+		if (last_status == 0 && cur_status == 1) {
+			/* set page 160, reg 17, bit 2, val 1 */
+			jlsemi_set_bits(phydev, JL2XXX_PAGE160, JL2XXX_REG17, (1 << 2));
+			/* set page 190, reg 23, bit 15, val 1 */
+			jlsemi_set_bits(phydev, JL2XXX_PAGE190, JL2XXX_REG23, (1 << 15));
+		}
+		last_status = cur_status;
+
+		msleep(100);
+	}
+
+	return 0;
+}
+
+int jl1xxx_wol_dynamic_op_get(struct phy_device *phydev)
+{
+	return jlsemi_fetch_bit(phydev, JL1XXX_PAGE129,
+				JL1XXX_WOL_CTRL_REG, JL1XXX_WOL_DIS);
+}
+
+int jl2xxx_wol_dynamic_op_get(struct phy_device *phydev)
+{
+	return jlsemi_fetch_bit(phydev, JL2XXX_WOL_CTRL_PAGE,
+				JL2XXX_WOL_CTRL_REG, JL2XXX_WOL_EN);
+}
+
+static int jl1xxx_wol_static_op_set(struct phy_device *phydev)
+{
+	int err;
+
+	err = jl1xxx_wol_dynamic_op_set(phydev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl1xxx_intr_ack_event(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->intr.enable & JL1XXX_INTR_STATIC_OP_EN) {
+		err = phy_read(phydev, JL1XXX_INTR_STATUS_REG);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+int jl1xxx_intr_static_op_set(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int err;
+	int ret = 0;
+
+	if (priv->intr.enable & JL1XXX_INTR_LINK_CHANGE_EN)
+		ret |= JL1XXX_INTR_LINK;
+	if (priv->intr.enable & JL1XXX_INTR_AN_ERR_EN)
+		ret |= JL1XXX_INTR_AN_ERR;
+
+	err = jlsemi_set_bits(phydev, JL1XXX_PAGE7,
+			      JL1XXX_INTR_REG, ret);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int jl2xxx_wol_static_op_set(struct phy_device *phydev)
+{
+	int err;
+
+	err = jl2xxx_wol_dynamic_op_set(phydev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl1xxx_wol_dynamic_op_set(struct phy_device *phydev)
+{
+	int err;
+
+	err = jl1xxx_wol_cfg_rmii(phydev);
+	if (err < 0)
+		return err;
+
+	err = jl1xxx_wol_enable(phydev, true);
+	if (err < 0)
+		return err;
+
+	err = jl1xxx_wol_store_mac_addr(phydev);
+	if (err < 0)
+		return err;
+
+	if (jl1xxx_wol_receive_check(phydev)) {
+		err = jl1xxx_wol_clear(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+int jl2xxx_wol_dynamic_op_set(struct phy_device *phydev)
+{
+	int err;
+
+	err = jl2xxx_wol_enable(phydev, true);
+	if (err < 0)
+		return err;
+
+	err = jl2xxx_wol_clear(phydev);
+	if (err < 0)
+		return err;
+
+	err = jl2xxx_wol_active_low_polarity(phydev, true);
+	if (err < 0)
+		return err;
+
+	err = jl2xxx_store_mac_addr(phydev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl2xxx_intr_ack_event(struct phy_device *phydev)
+{
+	int err;
+
+	err = jlsemi_read_paged(phydev, JL2XXX_PAGE2627,
+				JL2XXX_INTR_STATUS_REG);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl2xxx_intr_static_op_set(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+	int ret = 0;
+
+	if (priv->intr.enable & JL2XXX_INTR_LINK_CHANGE_EN)
+		ret |= JL2XXX_INTR_LINK_CHANGE;
+	if (priv->intr.enable & JL2XXX_INTR_AN_ERR_EN)
+		ret |= JL2XXX_INTR_AN_ERR;
+	if (priv->intr.enable & JL2XXX_INTR_AN_COMPLETE_EN)
+		ret |= JL2XXX_INTR_AN_COMPLETE;
+	if (priv->intr.enable & JL2XXX_INTR_AN_PAGE_RECE)
+		ret |= JL2XXX_INTR_AN_PAGE;
+
+	err = jlsemi_set_bits(phydev, JL2XXX_PAGE2626,
+			      JL2XXX_INTR_CTRL_REG, ret);
+	if (err < 0)
+		return err;
+
+	err = jlsemi_set_bits(phydev, JL2XXX_PAGE158,
+			      JL2XXX_INTR_PIN_REG,
+			      JL2XXX_INTR_PIN_EN);
+	if (err < 0)
+		return err;
+
+	err = jlsemi_set_bits(phydev, JL2XXX_PAGE160,
+			      JL2XXX_PIN_EN_REG,
+			      JL2XXX_PIN_OUTPUT);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int jl1xxx_operation_args_get(struct phy_device *phydev)
+{
+	jl1xxx_led_operation_args(phydev);
+	jl1xxx_wol_operation_args(phydev);
+	jl1xxx_intr_operation_args(phydev);
+	jl1xxx_mdi_operation_args(phydev);
+	jl1xxx_rmii_operation_args(phydev);
+
+	return 0;
+}
+
+int jl2xxx_operation_args_get(struct phy_device *phydev)
+{
+	jl2xxx_led_operation_args(phydev);
+	jl2xxx_fld_operation_args(phydev);
+	jl2xxx_wol_operation_args(phydev);
+	jl2xxx_intr_operation_args(phydev);
+	jl2xxx_downshift_operation_args(phydev);
+	jl2xxx_rgmii_operation_args(phydev);
+	jl2xxx_patch_operation_args(phydev);
+	jl2xxx_clk_operation_args(phydev);
+	jl2xxx_work_mode_operation_args(phydev);
+	jl2xxx_lpbk_operation_args(phydev);
+	jl2xxx_slew_rate_operation_args(phydev);
+	jl2xxx_rxc_out_operation_args(phydev);
+
+	return 0;
+}
+
+int jl1xxx_static_op_init(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->led.enable & JL1XXX_LED_STATIC_OP_EN) {
+		err = jl1xxx_led_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->wol.enable & JL1XXX_WOL_STATIC_OP_EN) {
+		err = jl1xxx_wol_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->intr.enable & JL1XXX_INTR_STATIC_OP_EN) {
+		err = jl1xxx_intr_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->mdi.enable & JL1XXX_MDI_STATIC_OP_EN) {
+		err = jl1xxx_mdi_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->rmii.enable & JL1XXX_RMII_STATIC_OP_EN) {
+		err = jl1xxx_rmii_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+int jl2xxx_static_sgmii_2_utp_mode_core_vol_adjust(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int mode;
+	int err;
+
+	mode = jlsemi_read_paged(phydev, JL2XXX_PAGE18, JL2XXX_WORK_MODE_REG);
+	/* Can only be used in sgmii->utp mode */
+	if (((priv->work_mode.enable & JL2XXX_WORK_MODE_STATIC_OP_EN) &&
+	   (priv->work_mode.mode == JL2XXX_UTP_SGMII_MODE)) ||
+	   ((mode & JL2XXX_WORK_MODE_MASK) == JL2XXX_UTP_SGMII_MODE)) {
+		// page 257, reg 29, bit6:  1->1V, 0->0.9V
+		err = jlsemi_set_bits(phydev, JL2XXX_PAGE257,
+					JL2XXX_ANA_PM0_REG,
+					JL2XXX_BUCK_SEL_VOUT_CFG);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+int jl2xxx_static_op_init(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->patch.enable & JL2XXX_PATCH_STATIC_OP_EN) {
+		err = jl2xxx_patch_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->led.enable & JL2XXX_LED_STATIC_OP_EN) {
+		err = jl2xxx_led_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->fld.enable & JL2XXX_FLD_STATIC_OP_EN) {
+		err = jl2xxx_fld_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->wol.enable & JL2XXX_WOL_STATIC_OP_EN) {
+		err = jl2xxx_wol_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->intr.enable & JL2XXX_INTR_STATIC_OP_EN) {
+		err = jl2xxx_intr_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->downshift.enable & JL2XXX_DSFT_STATIC_OP_EN) {
+		err = jl2xxx_downshift_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->rgmii.enable & JL2XXX_RGMII_STATIC_OP_EN) {
+		err = jl2xxx_rgmii_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->clk.enable & JL2XXX_CLK_STATIC_OP_EN) {
+		err = jl2xxx_clk_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->work_mode.enable & JL2XXX_WORK_MODE_STATIC_OP_EN) {
+		err = jl2xxx_work_mode_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	if (priv->lpbk.enable & JL2XXX_LPBK_STATIC_OP_EN) {
+		err = jl2xxx_lpbk_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+#if 0
+	if (priv->slew_rate.enable & JL2XXX_SLEW_RATE_STATIC_OP_EN) {
+		err = jl2xxx_slew_rate_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+#endif
+	if (priv->rxc_out.enable & JL2XXX_RXC_OUT_STATIC_OP_EN) {
+		err = jl2xxx_rxc_out_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+	// SGMII-TO-UTP mode adjust core voltage to 1.0V
+	err = jl2xxx_static_sgmii_2_utp_mode_core_vol_adjust(phydev);
+	if (err < 0)
+		return err;
+	return 0;
+}
+
+int jl2xxx_pre_init(struct phy_device *phydev, struct jl_patch *patch)
+{
+	bool check;
+
+	check = patch->check(phydev, patch);
+	if (!check)
+		return 0;
+	patch->load(phydev, patch);
+	patch->verify(phydev, patch);
+
+	return 1;
+}
+
+int jlsemi_soft_reset(struct phy_device *phydev)
+{
+	int err;
+
+	err = jlsemi_set_bits(phydev, JL2XXX_PAGE0,
+			      JL2XXX_BMCR_REG, JL2XXX_SOFT_RESET);
+	if (err < 0)
+		return err;
+	/* Wait soft reset complete*/
+	msleep(600);
+
+	return 0;
+}
+
+/********************** Convenience function for phy **********************/
+
+/**
+ * jlsemi_write_page() - write the page register
+ * @phydev: a pointer to a &struct phy_device
+ * @page: page values
+ */
+int jlsemi_write_page(struct phy_device *phydev, int page)
+{
+	return phy_write(phydev, JLSEMI_PAGE31, page);
+}
+
+/**
+ * jlsemi_read_page() - write the page register
+ * @phydev: a pointer to a &struct phy_device
+ *
+ * Return: get page values at present
+ */
+int jlsemi_read_page(struct phy_device *phydev)
+{
+	return phy_read(phydev, JLSEMI_PAGE31);
+}
+
+/**
+ * __jlsemi_save_page() - save the page value
+ *@phydev: a pointer to a &struct phy_device
+ *
+ * Return: save page value
+ */
+static inline int __jlsemi_save_page(struct phy_device *phydev)
+{
+	return jlsemi_read_page(phydev);
+}
+
+/**
+ * __jlsemi_select_page() - restore the page register
+ * @phydev: a pointer to a &struct phy_device
+ * @page: the page
+ *
+ * Return:
+ * @oldpgae: this is last page value
+ * @ret: if page is change it will return new page value
+ */
+static inline int __jlsemi_select_page(struct phy_device *phydev, int page)
+{
+	int ret, oldpage;
+
+	oldpage = ret = __jlsemi_save_page(phydev);
+	if (ret < 0)
+		return ret;
+
+	if (oldpage != page) {
+		ret = jlsemi_write_page(phydev, page);
+		if (ret < 0)
+			return ret;
+	}
+
+	return oldpage;
+}
+
+/**
+ * __jlsemi_restore_page() - restore the page register
+ * @phydev: a pointer to a &struct phy_device
+ * @oldpage: the old page, return value from __jlsemi_save_page() or
+ * __jlsemi_select_page()
+ * @ret: operation's return code
+ *
+ * Returns:
+ *   @oldpage if it was a negative value, otherwise
+ *   @ret if it was a negative errno value, otherwise
+ *   phy_write_page()'s negative value if it were in error, otherwise
+ *   @ret
+ */
+static inline int __jlsemi_restore_page(struct phy_device *phydev,
+					int oldpage, int ret)
+{
+	int r;
+
+	if (oldpage >= 0) {
+		r = jlsemi_write_page(phydev, oldpage);
+
+		/* Propagate the operation return code if the page write
+		 * was successful.
+		 */
+		if (ret >= 0 && r < 0)
+			ret = r;
+	} else {
+		/* Propagate the phy page selection error code */
+		ret = oldpage;
+	}
+
+	return ret;
+}
+
+/**
+ * __jlsemi_modify_reg() - Convenience function for modifying a PHY register
+ * @phydev: a pointer to a &struct phy_device
+ * @regnum: register number
+ * @mask: bit mask of bits to clear
+ * @set: bit mask of bits to set
+ *
+ * Returns negative errno, 0 if there was no change, and 1 in case of change
+ */
+static inline int __jlsemi_modify_reg(struct phy_device *phydev,
+				      u32 regnum, u16 mask, u16 set)
+{
+	int newval, ret;
+
+	ret = phy_read(phydev, regnum);
+	if (ret < 0)
+		return ret;
+
+	newval = (ret & ~mask) | set;
+	if (newval == ret)
+		return 0;
+
+	ret = phy_write(phydev, regnum, newval);
+
+	return ret < 0 ? ret : 1;
+}
+
+/**
+ * jlsemi_modify_paged_reg() - Function for modifying a paged register
+ * @phydev: a pointer to a &struct phy_device
+ * @page: the page for the phy
+ * @regnum: register number
+ * @mask: bit mask of bits to clear
+ * @set: bit mask of bits to set
+ *
+ * Returns negative errno, 0 if there was no change, and 1 in case of change
+ */
+int jlsemi_modify_paged_reg(struct phy_device *phydev,
+			    int page, u32 regnum,
+			    u16 mask, u16 set)
+{
+	int ret = 0, oldpage;
+
+	oldpage = __jlsemi_select_page(phydev, page);
+	if (oldpage >= 0)
+		ret = __jlsemi_modify_reg(phydev, regnum, mask, set);
+
+	return __jlsemi_restore_page(phydev, oldpage, ret);
+}
+
+/**
+ * jlsemi_set_bits() - Convenience function for setting bits in a PHY register
+ * @phydev: a pointer to a &struct phy_device
+ * @page: the page for the phy
+ * @regnum: register number to write
+ * @val: bits to set
+ */
+int jlsemi_set_bits(struct phy_device *phydev,
+		    int page, u32 regnum, u16 val)
+{
+	return jlsemi_modify_paged_reg(phydev, page, regnum, 0, val);
+}
+
+/**
+ * jlsemi_clear_bits - Convenience function for clearing bits in a PHY register
+ * @phydev: the phy_device struct
+ * @page: the page for the phy
+ * @regnum: register number to write
+ * @val: bits to clear
+ */
+int jlsemi_clear_bits(struct phy_device *phydev,
+		      int page, u32 regnum, u16 val)
+{
+	return jlsemi_modify_paged_reg(phydev, page, regnum, val, 0);
+}
+
+/**
+ * jlsemi_fetch_bit() - Convenience function for setting bits in a PHY register
+ * @phydev: a pointer to a &struct phy_device
+ * @page: the page for the phy
+ * @regnum: register number to write
+ * @val: bit to get
+ *
+ * Note:
+ * you only get one bit at meanwhile
+ *
+ */
+int jlsemi_fetch_bit(struct phy_device *phydev,
+		   int page, u32 regnum, u16 val)
+{
+	int ret = 0, oldpage;
+
+	oldpage = __jlsemi_select_page(phydev, page);
+	if (oldpage >= 0) {
+		ret = phy_read(phydev, regnum);
+		if (ret < 0)
+			return ret;
+		ret = ((ret & val) == val) ? 1 : 0;
+	}
+
+	return __jlsemi_restore_page(phydev, oldpage, ret);
+}
+
+/**
+ * jlsemi_read_paged() - Convenience function for reading a paged register
+ * @phydev: a pointer to a &struct phy_device
+ * @page: the page for the phy
+ * @regnum: register number
+ *
+ * Same rules as for phy_read().
+ */
+int jlsemi_read_paged(struct phy_device *phydev, int page, u32 regnum)
+{
+	int ret = 0, oldpage;
+
+	oldpage = __jlsemi_select_page(phydev, page);
+	if (oldpage >= 0)
+		ret = phy_read(phydev, regnum);
+
+	return __jlsemi_restore_page(phydev, oldpage, ret);
+}
+
+/**
+ * jlsemi_patch_dynamic_op_set() - Convenience function for dynamic set patch
+ * @phydev: a pointer to a &struct phy_device
+ *
+ */
+int jlsemi_patch_dynamic_op_set(struct phy_device *phydev)
+{
+	return jl2xxx_patch_dynamic_op_set(phydev);
+}
+
+#if (KERNEL_VERSION(4, 0, 0) > LINUX_VERSION_CODE)
+int jlsemi_drivers_register(struct phy_driver *phydrvs, int size)
+{
+	int i, j;
+	int ret;
+
+	printk("cy: enter jlsemi_drivers_register 2\n");
+	for (i = 0; i < size; i++) {
+		ret = phy_driver_register(&phydrvs[i]);
+		if (ret)
+			goto err;
+	}
+
+	return 0;
+
+err:
+	for (j = 0; j < i; j++)
+		phy_driver_unregister(&phydrvs[j]);
+
+	printk("cy: enter jlsemi_drivers_register fail\n");
+	return ret;
+}
+
+void jlsemi_drivers_unregister(struct phy_driver *phydrvs, int size)
+{
+	int i;
+
+	printk("cy: exit jlsemi_drivers_register 1\n");
+	for (i = 0; i < size; i++)
+		phy_driver_unregister(&phydrvs[i]);
+}
+#else
+#endif
diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi-core.h b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi-core.h
new file mode 100755
index 0000000..9010042
--- /dev/null
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi-core.h
@@ -0,0 +1,465 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ *
+ * Copyright (C) 2021 JLSemi Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _JLSEMI_CORE_H
+#define _JLSEMI_CORE_H
+
+#define JLSEMI_KERNEL_DEVICE_TREE_USE	0
+#define JLSEMI_DEBUG_INFO 1
+
+#include <linux/phy.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+#include <dt-bindings/phy/jlsemi-dt-phy.h>
+#else
+#include "jlsemi-dt-phy.h"
+#endif
+
+#define JL1XXX_PHY_ID		0x937c4023
+#define JL2XXX_PHY_ID		0x937c4032
+#define JLSEMI_PHY_ID_MASK	0xfffffff0
+
+#define JL1XXX_PAGE0		0
+#define JL1XXX_PAGE7		7
+#define JL1XXX_INTR_REG		19
+#define JL1XXX_INTR_LINK	BIT(13)
+#define JL1XXX_INTR_AN_ERR	BIT(11)
+#define JL1XXX_LED_REG		19
+#define JL1XXX_LED_EN		BIT(3)
+#define JL1XXX_INTR_STATUS_REG	30
+
+#define JL1XXX_PAGE7		7
+#define JL1XXX_RMII_CTRL_REG	16
+#define JL1XXX_RMII_OUT		BIT(12)
+#define JL1XXX_RMII_MODE	BIT(3)
+
+#define JL1XXX_PAGE129		129
+#define JL1XXX_LED_MODE_REG	24
+#define JL1XXX_MAC_ADDR0_REG	25
+#define JL1XXX_MAC_ADDR1_REG	26
+#define JL1XXX_MAC_ADDR2_REG	27
+#define JL1XXX_WOL_CTRL_REG	28
+#define JL1XXX_WOL_DIS		BIT(15)
+#define JL1XXX_WOL_CLEAR	BIT(1)
+#define JL1xxx_WOL_RECEIVE	BIT(0)
+#define ADDR8_HIGH_TO_LOW(n)	((n >> 4) | (n << 4))
+
+#define JL1XXX_PAGE24		24
+#define JL1XXX_REG24		24
+#define JL1XXX_MDI_TX_BM_MASK	0x1c00
+#define JL1XXX_MDI_TX_BM(n)	(n << 10)
+#define JL1XXX_MDI_TX_SRN	BIT(0)
+
+#define JL1XXX_PAGE7		7
+#define JL1XXX_REG16		16
+#define JL1XXX_RMII_MODE		BIT(3)
+#define JL1XXX_RMII_CLK_50M_INPUT	BIT(12)
+#define JL1XXX_RMII_TX_SKEW_MASK	(0xf << 8)
+#define JL1XXX_RMII_TX_SKEW(n)		((n << 8) & JL1XXX_RMII_TX_SKEW_MASK)
+#define JL1XXX_RMII_RX_SKEW_MASK	(0xf << 4)
+#define JL1XXX_RMII_RX_SKEW(n)		((n << 4) & JL1XXX_RMII_RX_SKEW_MASK)
+#define JL1XXX_RMII_CRS_DV		BIT(2)
+
+#define JL2XXX_PAGE0		0
+#define JL2XXX_BMCR_REG		0x0000
+#define JL2XXX_SOFT_RESET	BIT(15)
+#define JL2XXX_SPEED_LSB	BIT(13)
+#define JL2XXX_AUTONEG_EN	BIT(12)
+#define JL2XXX_SPEED_MSB	BIT(6)
+#define JL2XXX_DSFT_CTRL_REG	17
+#define JL2XXX_DSFT_EN		BIT(12)
+#define JL2XXX_DSFT_SMART_EN	BIT(13)
+#define JL2XXX_DSFT_TWO_WIRE_EN	BIT(14)
+#define JL2XXX_DSFT_AN_ERR_EN	BIT(15)
+#define JL2XXX_DSFT_STL_MASK	0x03e0
+#define JL2XXX_DSFT_STL_CNT(n)	(((n << 5) & JL2XXX_DSFT_STL_MASK))
+#define JL2XXX_DSFT_AN_MASK	0x001f
+#define JL2XXX_DSFT_CNT_MAX	32
+#define JL2XXX_PHY_INFO_REG	29
+#define JL2XXX_PATCH_MASK	0xffff
+#define JL2XXX_SW_MASK		0xffff
+#define JL2XXX_AUTO_GAIN_DIS	BIT(6)
+
+#define JLSEMI_PAGE31		0x001f
+#define JL2XXX_WOL_CTRL_PAGE	0x0012
+#define JL2XXX_WOL_CTRL_REG	0x0015
+#define JL2XXX_WOL_STAS_PAGE	0x1200
+#define JL2XXX_WOL_STAS_REG	0x0010
+#define JL2XXX_MAC_ADDR2_REG	0x0011
+#define JL2XXX_MAC_ADDR1_REG	0x0012
+#define JL2XXX_MAC_ADDR0_REG	0x0013
+#define JL2XXX_WOL_EVENT	BIT(1)
+#define JL2XXX_WOL_POLARITY	BIT(14)
+#define JL2XXX_WOL_EN		BIT(15)
+#define JL2XXX_WOL_GLB_EN	BIT(6)
+
+#define JL2XXX_PAGE2626		2626
+#define JL2XXX_INTR_CTRL_REG	18
+#define JL2XXX_INTR_LINK_CHANGE	BIT(4)
+#define JL2XXX_INTR_AN_COMPLETE	BIT(3)
+#define JL2XXX_INTR_AN_PAGE	BIT(2)
+#define JL2XXX_INTR_AN_ERR	BIT(0)
+
+#define JL2XXX_PAGE2627		2627
+#define JL2XXX_INTR_STATUS_REG	29
+#define JL2XXX_CLK_CTRL_REG	25
+#define JL2XXX_CLK_OUT_PIN	BIT(0)
+#define JL2XXX_CLK_SSC_EN	BIT(3)
+#define JL2XXX_CLK_125M_OUT	BIT(11)
+#define JL2XXXX_CLK_SRC		BIT(12)
+
+#define JL2XXX_PAGE158		158
+#define JL2XXX_INTR_PIN_REG	16
+#define JL2XXX_INTR_PIN_EN	BIT(14)
+
+#define JL2XXX_PAGE160		160
+#define JL2XXX_PIN_EN_REG	21
+#define JL2XXX_PIN_OUTPUT	BIT(11)
+
+#define JL2XXX_PAGE3336		3336
+#define JL2XXX_RGMII_CTRL_REG	17
+
+#define JL2XXX_PAGE18		18
+#define JL2XXX_RXC_OUT_REG	21
+#define JL2XXX_RXC_OUT		BIT(14)
+
+#define JL2XXX_WORK_MODE_REG	21
+#define JL2XXX_WORK_MODE_MASK	0x7
+
+#define JL2XXX_PAGE160		160
+#define JL2XXX_REG25		25
+#define JL2XXX_CPU_RESET	BIT(3)
+
+#define JL2XXX_PAGE173		173
+#define JL2XXX_PATCH_REG	0x0010
+#define JL2XXX_REG16		16
+#define JL2XXX_REG17		17
+#define JL2XXX_LOAD_GO		0
+#define JL2XXX_LOAD_DATA0	0x3a01
+#define JL2XXX_REG20		20
+#define JL2XXX_REG21		21
+#define JL2XXX_LPBK_MODE_MASK	0x6
+#define JL2XXX_LPBK_PMD_MODE	BIT(2)
+#define JL2XXX_LPBK_EXT_MODE	BIT(1)
+
+#define JL2XXX_PAGE174		174
+
+#define JL2XXX_REG29		29
+
+#define JL2XXX_PAGE179		179
+
+#define JL2XXX_PAGE181		181
+#define JL2XXX_REG18		18
+#define JL2XXX_SERDES_LINK		BIT(2)
+
+#define JL2XXX_PAGE190		190
+#define JL2XXX_REG23		23
+
+#define JL2XXX_PAGE191		191
+#define JL2XXX_RGMII_CFG	BIT(3)
+
+#define JL2XXX_PAGE257		257
+#define JL2XXX_ANA_PM0_REG	29
+#define JL2XXX_BUCK_SEL_VOUT_CFG	BIT(6)
+
+
+#define JL2XXX_PAGE258		258
+#define JL2XXX_SLEW_RATE_CTRL_REG	23
+#define JL2XXX_SLEW_RATE_EN		BIT(12)
+#define JL2XXX_SLEW_RATE_REF_CLK	BIT(13)
+#define JL2XXX_SLEW_RATE_SEL_CLK	BIT(14)
+
+#define JL2XXX_REG20		20
+#define JL2XXX_SPEED1000_NO_AN	(BIT(11) | BIT(10))
+
+#define LED_PERIOD_MASK		0xff00
+#define LEDPERIOD(n)		((n << 8) & LED_PERIOD_MASK)
+#define LED_ON_MASK		0x00ff
+#define LEDON(n)		((n << 0) & LED_ON_MASK)
+
+#define ADVERTISE_FIBER_1000HALF	0x40
+#define ADVERTISE_FIBER_1000FULL	0x20
+
+/*************************************************************************/
+struct jl_patch {
+	const u32 *data;
+	u16 data_len;
+	const u16 version;
+	struct {
+		const u16 *info;
+		u16 info_len;
+	} phy;
+	bool (*check)(struct phy_device *phydev, struct jl_patch *patch);
+	int (*load)(struct phy_device *phydev, struct jl_patch *patch);
+	int (*verify)(struct phy_device *phydev, struct jl_patch *patch);
+};
+
+struct jl_hw_stat {
+	const char *string;
+	u8 reg;
+	u16 page;
+	u16 mask;
+	u16 enable;
+};
+
+static const struct jl_hw_stat jl_phy[] = {
+	{
+		.string = "page0,reg0",
+		.enable = true,
+		.page = 0,
+		.reg = 0,
+	}, {
+		.string = "page0,reg1",
+		.enable = false,
+		.page = 0,
+		.reg = 1,
+	},
+};
+
+static const struct jl_hw_stat jl2xxx_hw_stats[] = {
+	{
+		.string	= "phy_patch_version",
+		.reg	= JL2XXX_PATCH_REG,
+		.page	= JL2XXX_PAGE174,
+		.mask	= JL2XXX_PATCH_MASK,
+	}, {
+		.string	= "phy_software_version",
+		.reg	= JL2XXX_PHY_INFO_REG,
+		.page	= JL2XXX_PAGE0,
+		.mask	= JL2XXX_SW_MASK,
+	},
+};
+
+struct jl_led_ctrl {
+	u32 enable;			/* LED control enable */
+	u32 mode;			/* LED work mode */
+	u32 global_period;		/* LED global twinkle period */
+	u32 global_on;			/* LED global twinkle hold on time */
+	u32 gpio_output;		/* LED is used as gpio output */
+	u32 polarity;			/* LED polarity */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_fld_ctrl {
+	u32 enable;			/* Fast link down control enable */
+	u32 delay;			/* Fast link down time */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_wol_ctrl {
+	u32 enable;			/* Wake On LAN control enable */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_intr_ctrl {
+	u32 enable;			/* Interrupt control enable */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_downshift_ctrl {
+	u32 enable;			/* Downshift control enable */
+	u32 count;			/* Downshift control count */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_rgmii_ctrl {
+	u32 enable;			/* Rgmii control enable */
+	u32 rx_delay;			/* Rgmii control rx delay */
+	u32 tx_delay;			/* Rgmii control tx delay */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_patch_ctrl {
+	u32 enable;			/* Patch control enable */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_clk_ctrl {
+	u32 enable;			/* Clock 125M control enable */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_work_mode_ctrl {
+	u32 enable;			/* Work mode control enable */
+	u32 mode;			/* Work mode select mode */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_loopback_ctrl {
+	u32 enable;			/* Loopback control enable */
+	u32 mode;			/* Loopback select mode */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_mdi_ctrl {
+	u32 enable;			/* Mdi control enable */
+	u32 rate;			/* Mdi select Rate */
+	u32 amplitude;			/* Mdi select amplitude */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_rmii_ctrl {
+	u32 enable;			/* Rmii control enable */
+	u32 tx_timing;			/* Rmii modify tx timing */
+	u32 rx_timing;			/* Rmii modify rx timing */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_slew_rate_ctrl {
+	u32 enable;			/* Slew rate control enable */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl_rxc_out_ctrl {
+	u32 enable;			/* Rx clock out control enable */
+	bool inited;			/* Only execute once flag */
+	bool ethtool;			/* Whether the ethtool is supported */
+};
+
+struct jl1xxx_priv {
+	struct jl_led_ctrl led;
+	struct jl_wol_ctrl wol;
+	struct jl_intr_ctrl intr;
+	bool static_inited;		/* Initialization flag */
+	struct jl_mdi_ctrl mdi;
+	struct jl_rmii_ctrl rmii;
+};
+
+struct jl2xxx_priv {
+	struct jl_led_ctrl led;
+	struct jl_fld_ctrl fld;
+	struct jl_wol_ctrl wol;
+	struct jl_intr_ctrl intr;
+	struct jl_downshift_ctrl downshift;
+	struct jl_rgmii_ctrl rgmii;
+	struct jl_patch_ctrl patch;
+	struct jl_clk_ctrl clk;
+	const struct jl_hw_stat *hw_stats;
+	bool static_inited;		/* Initialization flag */
+	int nstats;			/* Record for dynamic operation */
+	u64 *stats;			/* Pointer for dynamic operation */
+	struct jl_work_mode_ctrl work_mode;
+	struct jl_loopback_ctrl lpbk;
+	struct jl_slew_rate_ctrl slew_rate;
+	struct jl_rxc_out_ctrl rxc_out;
+};
+
+/* macros to simplify debug checking */
+#define JLSEMI_PHY_MSG(msg, args...) printk(KERN_INFO msg, ## args)
+
+/************************* JLSemi iteration code *************************/
+struct device *jlsemi_get_mdio(struct phy_device *phydev);
+
+int jl2xxx_downshift_dynamic_op_get(struct phy_device *phydev, u8 *data);
+
+int jl2xxx_downshift_dynamic_op_set(struct phy_device *phydev, u8 cnt);
+
+int jlsemi_read_paged(struct phy_device *phydev, int page, u32 regnum);
+
+int jl2xxx_intr_ack_event(struct phy_device *phydev);
+
+int jl2xxx_intr_static_op_set(struct phy_device *phydev);
+
+int jl1xxx_intr_ack_event(struct phy_device *phydev);
+
+int jl1xxx_intr_static_op_set(struct phy_device *phydev);
+
+int jl2xxx_wol_dynamic_op_get(struct phy_device *phydev);
+
+int jl2xxx_wol_dynamic_op_set(struct phy_device *phydev);
+
+int jl1xxx_wol_dynamic_op_get(struct phy_device *phydev);
+
+int jl1xxx_wol_dynamic_op_set(struct phy_device *phydev);
+
+int jl2xxx_fld_dynamic_op_get(struct phy_device *phydev, u8 *msecs);
+
+int jl2xxx_fld_dynamic_op_set(struct phy_device *phydev, const u8 *msecs);
+
+int jl1xxx_operation_args_get(struct phy_device *phydev);
+
+int jl1xxx_static_op_init(struct phy_device *phydev);
+
+int jl2xxx_operation_args_get(struct phy_device *phydev);
+
+int jl2xxx_static_op_init(struct phy_device *phydev);
+
+int jlsemi_soft_reset(struct phy_device *phydev);
+
+int jl2xxx_pre_init(struct phy_device *phydev, struct jl_patch *patch);
+
+bool jl2xxx_read_fiber_status(struct phy_device *phydev);
+
+int jl2xxx_config_aneg_fiber(struct phy_device *phydev);
+
+/********************** Convenience function for phy **********************/
+
+/* Notice: You should change page 0 when you When you call it after */
+int jlsemi_write_page(struct phy_device *phydev, int page);
+
+int jlsemi_read_page(struct phy_device *phydev);
+
+int jlsemi_modify_paged_reg(struct phy_device *phydev,
+			    int page, u32 regnum,
+			    u16 mask, u16 set);
+
+int jlsemi_set_bits(struct phy_device *phydev,
+		    int page, u32 regnum, u16 val);
+
+int jlsemi_clear_bits(struct phy_device *phydev,
+		      int page, u32 regnum, u16 val);
+
+int jlsemi_fetch_bit(struct phy_device *phydev,
+		     int page, u32 regnum, u16 val);
+
+int jlsemi_drivers_register(struct phy_driver *phydrvs, int size);
+
+void jlsemi_drivers_unregister(struct phy_driver *phydrvs, int size);
+
+/**
+ * module_jlsemi_driver() - Helper macro for registering PHY drivers
+ * @__phy_drivers: array of PHY drivers to register
+ *
+ * Helper macro for PHY drivers which do not do anything special in module
+ * init/exit. Each module may only use this macro once, and calling it
+ * replaces module_init() and module_exit().
+ */
+#if (KERNEL_VERSION(4, 0, 0) > LINUX_VERSION_CODE)
+
+#define jlsemi_module_driver(__phy_drivers, __count)			\
+static int __init phy_module_init(void)					\
+{									\
+	return jlsemi_drivers_register(__phy_drivers, __count);		\
+}									\
+module_init(phy_module_init);						\
+static void __exit phy_module_exit(void)				\
+{									\
+	jlsemi_drivers_unregister(__phy_drivers, __count);		\
+}									\
+module_exit(phy_module_exit)
+
+#define module_jlsemi_driver(__phy_drivers)				\
+	jlsemi_module_driver(__phy_drivers, ARRAY_SIZE(__phy_drivers))
+
+#else
+
+#define module_jlsemi_driver(__phy_drivers)				\
+	module_phy_driver(__phy_drivers)
+#endif
+
+#endif /* _JLSEMI_CORE_H */
+
diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi-dt-phy.h b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi-dt-phy.h
new file mode 100755
index 0000000..0a6e221
--- /dev/null
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi-dt-phy.h
@@ -0,0 +1,341 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Device Tree constants for JLSemi PHY
+ *
+ * Author: Gangqiao Kuang
+ *
+ * Copyright (c) 2021 JLSemi Corporation
+ */
+
+#ifndef _DT_BINDINGS_JLSEMI_PHY_H
+#define _DT_BINDINGS_JLSEMI_PHY_H
+
+/**************************** Linux Version Compatible ********************/
+#define JLSEMI_DEV_COMPATIBLE	(KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
+#define JL2XXX_GET_STRING	(KERNEL_VERSION(4, 5, 0) <= LINUX_VERSION_CODE)
+#define JL2XXX_GET_STAT		(KERNEL_VERSION(4, 5, 0) <= LINUX_VERSION_CODE)
+#define JL2XXX_PHY_TUNABLE	(KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE)
+#define JLSEMI_PHY_WOL		(KERNEL_VERSION(3, 10, 0) < LINUX_VERSION_CODE)
+/*************************************************************************/
+
+/**************************** JLSemi Debug *******************************/
+#define JLSEMI_DEBUG_INFO	0
+/*************************************************************************/
+
+/************************* JLSemi Phy Init Reentrant *********************/
+#define JLSEMI_PHY_NOT_REENTRANT	false
+/*************************************************************************/
+
+/**************************** JL1XXX-LED *********************************/
+/* PHY LED Modes Select */
+#define JL1XXX_LED0_STRAP		(1 << 0)
+#define JL1XXX_LED0_EEE			(1 << 1)
+#define JL1XXX_LED0_100_ACTIVITY	(1 << 2)
+#define JL1XXX_LED0_10_ACTIVITY		(1 << 3)
+#define JL1XXX_LED0_100_LINK		(1 << 4)
+#define JL1XXX_LED0_10_LINK		(1 << 5)
+#define JL1XXX_LED1_STRAP		(1 << 8)
+#define JL1XXX_LED1_EEE			(1 << 9)
+#define JL1XXX_LED1_100_ACTIVITY	(1 << 10)
+#define JL1XXX_LED1_10_ACTIVITY		(1 << 11)
+#define JL1XXX_LED1_100_LINK		(1 << 12)
+#define JL1XXX_LED1_10_LINK		(1 << 13)
+
+/* PHY LED As Gpio Output Select */
+#define JL1XXX_GPIO_LED0_OUT		(1 << 2)
+#define JL1XXX_GPIO_LED1_OUT		(1 << 3)
+#define JL1XXX_GPIO_LED0_EN		(1 << 14)
+#define JL1XXX_GPIO_LED1_EN		(1 << 15)
+
+/* PHY LED Control Enable Mask Select */
+#define JL1XXX_LED_STATIC_OP_EN		(1 << 0)
+#define JL1XXX_LED_MODE_EN		(1 << 1)
+#define JL1XXX_LED_GLOABL_PERIOD_EN	(1 << 2)
+#define JL1XXX_LED_GLOBAL_ON_EN		(1 << 3)
+#define JL1XXX_LED_GPIO_OUT_EN		(1 << 4)
+//-----------------------------------------------------------------------//
+/* PHY LED Control Enable Mask Config */
+#define JL1XXX_LED_CTRL_EN	(0)
+
+/* PHY LED Modes Config */
+#define JL1XXX_CFG_LED_MODE	(JL1XXX_LED0_100_LINK | \
+				 JL1XXX_LED0_10_LINK | \
+				 JL1XXX_LED1_100_ACTIVITY | \
+				 JL1XXX_LED1_10_ACTIVITY)
+
+/* PHY LED As Gpio Output Config */
+#define JL1XXX_CFG_GPIO		(JL1XXX_GPIO_LED0_EN | \
+				 JL1XXX_GPIO_LED0_OUT | \
+				 JL1XXX_GPIO_LED1_EN | \
+				 JL1XXX_GPIO_LED1_OUT)
+
+/* PHY LED Global Period Config */
+#define JL1XXX_GLOBAL_PERIOD_MS		0x10
+
+/* PHY LED Global Hold On Config */
+#define JL1XXX_GLOBAL_ON_MS		0x8
+/**************************************************************************/
+
+/****************************** JL1XXX-WOL ********************************/
+/* PHY WOL Control Enable Mask Select */
+#define JL1XXX_WOL_STATIC_OP_EN		(1 << 0)
+//-----------------------------------------------------------------------//
+/* PHY WOL Control Enable Mask Config */
+#define JL1XXX_WOL_CTRL_EN	(0)
+
+/*************************************************************************/
+
+/***************************** JL1XXX-INTR *******************************/
+/* PHY Interrupt Control Enable Mask Select */
+#define JL1XXX_INTR_STATIC_OP_EN	(1 << 0)
+#define JL1XXX_INTR_LINK_CHANGE_EN	(1 << 1)
+#define JL1XXX_INTR_AN_ERR_EN		(1 << 2)
+//-----------------------------------------------------------------------//
+/* PHY Interrupt Irq Number Config */
+#define JL1XXX_INTR_IRQ			-1
+
+/* PHY Interrupt Control Enable Mask Config */
+#define JL1XXX_INTR_CTRL_EN	(0)
+/*************************************************************************/
+
+/**************************** JL1XXX-MDI *********************************/
+/* PHY MDI Control Mode Enable Mask Select */
+#define JL1XXX_MDI_STATIC_OP_EN		(1 << 0)
+#define JL1XXX_MDI_RATE_EN		(1 << 1)
+#define JL1XXX_MDI_AMPLITUDE_EN		(1 << 2)
+
+/* PHY MDI Rate Select */
+#define JL1XXX_MDI_RATE_STANDARD	0
+#define JL1XXX_MDI_RATE_ACCELERATE	1
+
+/* PHY MDI Amplitude Select */
+#define JL1XXX_MDI_AMPLITUDE0		0
+#define JL1XXX_MDI_AMPLITUDE1		1
+#define JL1XXX_MDI_AMPLITUDE2		2
+#define JL1XXX_MDI_AMPLITUDE3		3
+#define JL1XXX_MDI_AMPLITUDE4		4
+#define JL1XXX_MDI_AMPLITUDE5		5
+#define JL1XXX_MDI_AMPLITUDE6		6
+#define JL1XXX_MDI_AMPLITUDE7		7
+//-----------------------------------------------------------------------//
+/* PHY MDI Control Mode Enable Mask Config */
+#define JL1XXX_MDI_CTRL_EN		(0)
+
+/* PHY MDI Rate Config */
+#define JL1XXX_MDI_RATE			JL1XXX_MDI_RATE_ACCELERATE
+
+/* PHY MDI Amplitude Config */
+#define JL1XXX_MDI_AMPLITUDE		JL1XXX_MDI_AMPLITUDE4
+
+/*************************************************************************/
+
+/**************************** JL1XXX-RMII ********************************/
+/* PHY RMII Control Mode Enable Mask Select */
+#define JL1XXX_RMII_STATIC_OP_EN	(1 << 0)
+#define JL1XXX_RMII_MODE_EN		(1 << 1)
+#define JL1XXX_RMII_CLK_50M_INPUT_EN	(1 << 2)
+#define JL1XXX_RMII_TX_SKEW_EN		(1 << 3)
+#define JL1XXX_RMII_RX_SKEW_EN		(1 << 4)
+#define JL1XXX_RMII_CRS_DV_EN		(1 << 5)
+//-----------------------------------------------------------------------//
+/* PHY RMII Control Mode Enable Mask Config */
+#define JL1XXX_RMII_CTRL_EN		(0)
+
+/* PHY RMII Timing Config */
+#define JL1XXX_RMII_TX_TIMING		0xf
+#define JL1XXX_RMII_RX_TIMING		0xf
+
+/*************************************************************************/
+
+/**************************** JL2XXX-LED *********************************/
+/* PHY LED Modes Select*/
+#define JL2XXX_LED0_LINK10		(1 << 0)
+#define JL2XXX_LED0_LINK100		(1 << 1)
+#define JL2XXX_LED0_LINK1000		(1 << 3)
+#define JL2XXX_LED0_ACTIVITY		(1 << 4)
+#define JL2XXX_LED1_LINK10		(1 << 5)
+#define JL2XXX_LED1_LINK100		(1 << 6)
+#define JL2XXX_LED1_LINK1000		(1 << 8)
+#define JL2XXX_LED1_ACTIVITY		(1 << 9)
+#define JL2XXX_LED2_LINK10		(1 << 10)
+#define JL2XXX_LED2_LINK100		(1 << 11)
+#define JL2XXX_LED2_LINK1000		(1 << 13)
+#define JL2XXX_LED2_ACTIVITY		(1 << 14)
+/* mode_A = 0 and mode_B = 1 default mode_A */
+#define JL2XXX_LED_GLB_MODE_B		(1 << 15)
+
+/* PHY LED Polarity Select */
+#define JL2XXX_LED0_POLARITY		(1 << 12)
+#define JL2XXX_LED1_POLARITY		(1 << 11)
+#define JL2XXX_LED2_POLARITY		(1 << 10)
+
+/* PHY LED Control Enable Mask Select */
+#define JL2XXX_LED_STATIC_OP_EN		(1 << 0)
+#define JL2XXX_LED_MODE_EN		(1 << 1)
+#define JL2XXX_LED_GLOABL_PERIOD_EN	(1 << 2)
+#define JL2XXX_LED_GLOBAL_ON_EN		(1 << 3)
+#define JL2XXX_LED_POLARITY_EN		(1 << 4)
+
+//-----------------------------------------------------------------------//
+/* PHY LED Control Enable Mask Config */
+#define JL2XXX_LED_CTRL_EN	(0)
+
+/* PHY LED Modes Config */
+#define JL2XXX_CFG_LED_MODE	(JL2XXX_LED0_LINK10 | \
+				 JL2XXX_LED0_ACTIVITY | \
+				 JL2XXX_LED1_LINK100 | \
+				 JL2XXX_LED1_ACTIVITY | \
+				 JL2XXX_LED2_LINK1000 | \
+				 JL2XXX_LED2_ACTIVITY)
+
+/* PHY LED Polarity Config */
+#define JL2XXX_LED_POLARITY	(JL2XXX_LED0_POLARITY | \
+				 JL2XXX_LED1_POLARITY | \
+				 JL2XXX_LED2_POLARITY)
+
+/* PHY LED Global Period Config */
+#define JL2XXX_GLOBAL_PERIOD_MS		0x3
+
+/* PHY LED Global Hold On Config */
+#define JL2XXX_GLOBAL_ON_MS		0x2
+/*************************************************************************/
+
+/**************************** JL2XXX-FLD *********************************/
+/* PHY Fast Link Down Control Enable Mask Select */
+#define JL2XXX_FLD_STATIC_OP_EN		(1 << 0)
+//-----------------------------------------------------------------------//
+/* PHY Fast Link Down Control Enable Mask Config */
+#define JL2XXX_FLD_CTRL_EN		(0)
+
+/* PHY Fast Link Down Delay Config */
+#define JL2XXX_FLD_DELAY		0
+/*************************************************************************/
+
+/**************************** JL2XXX-WOL *********************************/
+/* PHY WOL Control Enable Mask Select */
+#define JL2XXX_WOL_STATIC_OP_EN		(1 << 0)
+
+//-----------------------------------------------------------------------//
+/* PHY WOL Control Enable Mask Config */
+#define JL2XXX_WOL_CTRL_EN	(0)
+/*************************************************************************/
+
+/**************************** JL2XXX-INTR ********************************/
+/* PHY Interrupt Control Enable Mask Select */
+#define JL2XXX_INTR_STATIC_OP_EN	(1 << 0)
+#define JL2XXX_INTR_LINK_CHANGE_EN	(1 << 1)
+#define JL2XXX_INTR_AN_ERR_EN		(1 << 2)
+#define JL2XXX_INTR_AN_COMPLETE_EN	(1 << 3)
+#define JL2XXX_INTR_AN_PAGE_RECE	(1 << 4)
+//-----------------------------------------------------------------------//
+/* PHY Interrupt Irq Number Config */
+#define JL2XXX_INTR_IRQ			-1
+
+/* PHY Interrupt Control Enable Mask Config */
+#define JL2XXX_INTR_CTRL_EN	(0)
+/*************************************************************************/
+
+/**************************** JL2XXX-DSFT ********************************/
+/* PHY Downshift Control Enable Mask */
+#define JL2XXX_DSFT_STATIC_OP_EN	(1 << 0)
+//-----------------------------------------------------------------------//
+/* PHY Downshift Control Enable Config */
+#define JL2XXX_DSFT_CTRL_EN	(0)
+
+/* PHY Downshift Count Config */
+#define JL2XXX_DSFT_AN_CNT		4
+/*************************************************************************/
+
+/**************************** JL2XXX-RGMII *******************************/
+/* PHY RGMII Control Mode Enable Mask Select */
+#define JL2XXX_RGMII_STATIC_OP_EN	(1 << 0)
+#define JL2XXX_RGMII_TX_DLY_EN		(1 << 1)
+#define JL2XXX_RGMII_RX_DLY_EN		(1 << 2)
+/* PHY RGMII DELAY BIT */
+#define JL2XXX_RGMII_TX_DLY_2NS		(1 << 8)
+#define JL2XXX_RGMII_RX_DLY_2NS		(1 << 9)
+//-----------------------------------------------------------------------//
+/* PHY RGMII Control Mode Enable Mask Config */
+#define JL2XXX_RGMII_CTRL_EN	(0)
+
+/*************************************************************************/
+
+/**************************** JL2XXX-PATCH *******************************/
+/* PHY Patch Control Mode Enable Mask Select */
+#define JL2XXX_PATCH_STATIC_OP_EN	(1 << 0)
+//-----------------------------------------------------------------------//
+/* PHY Patch Control Mode Enable Mask Config */
+#define JL2XXX_PATCH_CTRL_EN	(JL2XXX_PATCH_STATIC_OP_EN)
+
+/*************************************************************************/
+
+/**************************** JL2XXX-CLOCK *******************************/
+/* PHY Clock Control Mode Enable Mask Select */
+#define JL2XXX_CLK_STATIC_OP_EN		(1 << 0)
+#define JL2XXX_25M_CLK_OUT_EN		(1 << 1)
+#define JL2XXX_125M_CLK_OUT_EN		(1 << 2)
+#define JL2XXX_CLK_OUT_DIS		(1 << 3)
+//-----------------------------------------------------------------------//
+/* PHY Clock Control Mode Enable Mask Config */
+#define JL2XXX_CLK_CTRL_EN	(0)
+
+/*************************************************************************/
+
+/**************************** JL2XXX-WORK_MODE ***************************/
+/* PHY Work Mode Control Mode Enable Mask Select */
+#define JL2XXX_WORK_MODE_STATIC_OP_EN	(1 << 0)
+
+/* PHY Work Mode Select */
+#define JL2XXX_UTP_RGMII_MODE		0
+#define JL2XXX_FIBER_RGMII_MODE		1
+#define JL2XXX_UTP_FIBER_RGMII_MODE	2
+#define JL2XXX_UTP_SGMII_MODE		3
+#define JL2XXX_PHY_SGMII_RGMII_MODE	4
+#define JL2XXX_MAC_SGMII_RGMII_MODE	5
+#define JL2XXX_UTP_FIBER_FORCE_MODE1	6
+#define JL2XXX_UTP_FIBER_FORCE_MODE2	7
+//-----------------------------------------------------------------------//
+/* PHY Work Mode Control Mode Enable Mask Config */
+#define JL2XXX_WORK_MODE_CTRL_EN	(0)
+
+/* PHY Work Mode Config */
+#define JL2XXX_WORK_MODE_MODE		JL2XXX_UTP_RGMII_MODE
+
+/*************************************************************************/
+
+/**************************** JL2XXX-LOOPBACK ****************************/
+/* PHY Loopback Control Mode Enable Mask Select */
+#define JL2XXX_LPBK_STATIC_OP_EN	(1 << 0)
+
+/* PHY Loopback Mode Select */
+#define JL2XXX_LPBK_PCS_10M		0
+#define JL2XXX_LPBK_PCS_100M		1
+#define JL2XXX_LPBK_PCS_1000M		2
+#define JL2XXX_LPBK_PMD_1000M		3
+#define JL2XXX_LPBK_EXT_STUB_1000M	4
+//-----------------------------------------------------------------------//
+/* PHY Loopback Control Mode Enable Mask Config */
+#define JL2XXX_LPBK_CTRL_EN		(0)
+
+/* PHY Loopback Mode Config */
+#define JL2XXX_LPBK_MODE		JL2XXX_LPBK_PCS_1000M
+/*************************************************************************/
+
+/**************************** JL2XXX-SLEW_RATE ****************************/
+/* PHY Slew Rate Control Mode Enable Mask Select */
+#define JL2XXX_SLEW_RATE_STATIC_OP_EN	(1 << 0)
+//-----------------------------------------------------------------------//
+/* PHY Slew Rate Control Mode Enable Mask Config */
+#define JL2XXX_SLEW_RATE_CTRL_EN	(0)
+
+/*************************************************************************/
+
+/**************************** JL2XXX-RXC_OUT *****************************/
+/* PHY Rx Clock Out Control Mode Enable Mask Select */
+#define JL2XXX_RXC_OUT_STATIC_OP_EN	(1 << 0)
+//-----------------------------------------------------------------------//
+/* PHY Rx Clock Out Control Mode Enable Mask Config */
+#define JL2XXX_RXC_OUT_CTRL_EN		(0)
+
+/*************************************************************************/
+#endif
diff --git a/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi.c b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi.c
new file mode 100755
index 0000000..221ccd1
--- /dev/null
+++ b/lynq/R306_MTN/ap/os/linux/linux-3.4.x/drivers/net/phy/jlsemi.c
@@ -0,0 +1,675 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * drivers/net/phy/jlsemi.c
+ *
+ * Driver for JLSemi PHYs
+ *
+ * Author: Gangqiao Kuang <gqkuang@jlsemi.com>
+ *
+ * Copyright (c) 2021 JingLue Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include "jlsemi-core.h"
+#include <linux/phy.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/gmac/gmac.h>
+
+#define DRIVER_VERSION		"1.2.16"
+#define DRIVER_NAME_100M	"JL1xxx Fast Ethernet " DRIVER_VERSION
+#define DRIVER_NAME_1000M	"JL2xxx Gigabit Ethernet " DRIVER_VERSION
+
+MODULE_DESCRIPTION("JLSemi PHY driver");
+MODULE_AUTHOR("Gangqiao Kuang");
+MODULE_LICENSE("GPL");
+
+static int phy_port_state =  0;
+extern void gmac_event_notify(GMAC_NOTIFY_EVENT notify_type, void* puf);
+
+#if (JLSEMI_DEBUG_INFO)
+static int jlsemi_phy_reg_print(struct phy_device *phydev)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(jl_phy); i++) {
+		if (jl_phy[i].enable) {
+			ret = jlsemi_read_paged(phydev, jl_phy[i].page,
+						jl_phy[i].reg);
+			JLSEMI_PHY_MSG("%s: 0x%x\n", jl_phy[i].string, ret);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+#endif
+
+static int jl1xxx_probe(struct phy_device *phydev)
+{
+	struct device *dev = jlsemi_get_mdio(phydev);
+	struct jl1xxx_priv *jl1xxx = NULL;
+	int err;
+
+    printk("cy: jl1xxx_probe begin\n");
+	jl1xxx = devm_kzalloc(dev, sizeof(*jl1xxx), GFP_KERNEL);
+	if (!jl1xxx)
+		return -ENOMEM;
+
+	phydev->priv = jl1xxx;
+
+#if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+	if (!dev->of_node)
+		JLSEMI_PHY_MSG("%s: Find device node failed\n", __func__);
+#endif
+	err = jl1xxx_operation_args_get(phydev);
+	if (err < 0) {
+        //printk("cy: jl1xxx_operation_args_get fail\n");
+		return err;
+	}
+
+	if (jl1xxx->intr.enable & JL1XXX_INTR_STATIC_OP_EN)
+		phydev->irq = JL1XXX_INTR_IRQ;
+
+	jl1xxx->static_inited = false;
+
+    printk("cy: jl1xxx_probe success\n");
+	return 0;
+}
+
+static int jl1xxx_config_init(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int ret;
+
+    //printk("cy: jl1xxx_config_init begin\n");
+	if (!priv->static_inited) {
+#if (JLSEMI_DEBUG_INFO)
+		JLSEMI_PHY_MSG("jl1xxx_config_init_before:\n");
+		ret = jlsemi_phy_reg_print(phydev);
+		if (ret < 0)
+			return ret;
+#endif
+		ret = jl1xxx_static_op_init(phydev);
+		if (ret < 0)
+			return ret;
+#if (JLSEMI_DEBUG_INFO)
+		JLSEMI_PHY_MSG("jl1xxx_config_init_after:\n");
+		ret = jlsemi_phy_reg_print(phydev);
+		if (ret < 0)
+			return ret;
+#endif
+		priv->static_inited = JLSEMI_PHY_NOT_REENTRANT;
+	}
+
+	//ret = jlsemi_read_paged(phydev, 7, 16);
+    //printk("cy: jlsemi_read_paged 7 16 : %08x\n", ret);
+	//ret = ret & 0xefff;
+	//printk("cy: set to %08x\n", ret);
+	//jlsemi_set_bits(phydev, 7, 16, ret);
+	//mdelay(10);
+	//ret = jlsemi_read_paged(phydev, 7, 16);
+    //printk("cy: jlsemi_read_paged 7 16 : %08x\n", ret);
+    //printk("cy: jl1xxx_config_init success\n");
+	return 0;
+}
+
+static int jl1xxx_ack_interrupt(struct phy_device *phydev)
+{
+	int err;
+
+	err = jl1xxx_intr_ack_event(phydev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int jl1xxx_config_intr(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->intr.enable & JL1XXX_INTR_STATIC_OP_EN) {
+		err = jl1xxx_ack_interrupt(phydev);
+		if (err < 0)
+			return err;
+
+		err = jl1xxx_intr_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static int jl1xxx_read_status(struct phy_device *phydev)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int err, ret;
+
+    //printk("cy: jl1xxx_read_status begin\n");
+	if (priv->intr.enable & JL1XXX_INTR_STATIC_OP_EN) {
+		err = jl1xxx_ack_interrupt(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	//ret = jlsemi_read_paged(phydev, 0, 5);
+    //printk("cy: jl1xxx_read_status 0 5 : %08x\n", ret);
+	ret = genphy_read_status(phydev);
+    //printk("cy: jl1xxx_read_status finish %d\n", ret);
+	return ret;
+}
+
+static int jl1xxx_private_proc(struct phy_device *phydev)
+{
+	int err = 0;
+	int i = 0;
+	int islink = 0;
+	int org_phy_status = 0;
+	int new_phy_status = 0;
+
+    //printk("cy: jl1xxx_private_proc begin\n");
+	if(phydev->bus == NULL)
+		return 0;
+
+	org_phy_status = phy_port_state;
+	//islink = jlsemi_read_paged(phydev, 7, 16);
+    //printk("cy: jlsemi_read_paged 7 16 : %08x\n", islink);
+	//islink = jlsemi_read_paged(phydev, 0, 0);
+    //printk("cy: jlsemi_read_paged 0 0 : %08x\n", islink);
+	islink = jlsemi_read_paged(phydev, 0, 1);
+    //printk("cy: jlsemi_read_paged 0 1 : %08x\n", islink);
+	islink = (islink & 0x4)?1:0;
+	//islink = 0;
+
+	phy_port_state = islink;
+	if(islink == 1)
+		new_phy_status = 1;
+
+	
+	//printk("port.1 linkstatus=%d. ",phy_port_state);
+
+	//printk("portlinkstatus=%d.\n",phydev->link);
+
+	if((org_phy_status == 0)&&(new_phy_status == 1))
+	{
+		printk("cy:  gmac_event_notify GMAC_ETH_PHY_PLUGIN\n");
+		gmac_event_notify(GMAC_ETH_PHY_PLUGIN, NULL);
+	}
+
+	if((org_phy_status == 1)&&(new_phy_status == 0))
+	{
+		printk("cy:  gmac_event_notify GMAC_ETH_PHY_PLUGOUT\n");
+		gmac_event_notify(GMAC_ETH_PHY_PLUGOUT, NULL);
+	}
+
+    //printk("cy: jl1xxx_private_proc %d\n", islink);
+	return err;
+}
+
+static void jl1xxx_remove(struct phy_device *phydev)
+{
+	struct device *dev = jlsemi_get_mdio(phydev);
+	struct jl1xxx_priv *priv = phydev->priv;
+
+	if (priv)
+		devm_kfree(dev, priv);
+}
+
+#if (JLSEMI_PHY_WOL)
+static void jl1xxx_get_wol(struct phy_device *phydev,
+			   struct ethtool_wolinfo *wol)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int wol_en;
+
+	if (priv->wol.ethtool) {
+		wol->supported = WAKE_MAGIC;
+		wol->wolopts = 0;
+
+		wol_en = jl1xxx_wol_dynamic_op_get(phydev);
+
+		if (!wol_en)
+			wol->wolopts |= WAKE_MAGIC;
+	}
+}
+
+static int jl1xxx_set_wol(struct phy_device *phydev,
+			  struct ethtool_wolinfo *wol)
+{
+	struct jl1xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->wol.ethtool) {
+		if (wol->wolopts & WAKE_MAGIC) {
+			err = jl1xxx_wol_dynamic_op_set(phydev);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	return 0;
+}
+#endif
+
+static int jl1xxx_suspend(struct phy_device *phydev)
+{
+	return genphy_suspend(phydev);
+}
+
+static int jl1xxx_resume(struct phy_device *phydev)
+{
+	return genphy_resume(phydev);
+}
+
+static int jl2xxx_probe(struct phy_device *phydev)
+{
+	struct device *dev = jlsemi_get_mdio(phydev);
+	struct jl2xxx_priv *jl2xxx = NULL;
+	int err;
+
+    printk("cy: jl2xxx_probe begin\n");
+	jl2xxx = devm_kzalloc(dev, sizeof(*jl2xxx), GFP_KERNEL);
+	if (!jl2xxx)
+		return -ENOMEM;
+
+	phydev->priv = jl2xxx;
+
+#if (JLSEMI_KERNEL_DEVICE_TREE_USE)
+	if (!dev->of_node)
+		JLSEMI_PHY_MSG("%s: Find device node failed\n", __func__);
+#endif
+	err = jl2xxx_operation_args_get(phydev);
+	if (err < 0) {
+        printk("cy: jl2xxx_operation_args_get fail\n");
+		return err;
+	}
+
+	if (jl2xxx->intr.enable & JL2XXX_INTR_STATIC_OP_EN) {
+        printk("cy: intr.enable true\n");
+		phydev->irq = JL2XXX_INTR_IRQ;
+	}
+
+	jl2xxx->static_inited = false;
+	jl2xxx->nstats = ARRAY_SIZE(jl2xxx_hw_stats);
+	jl2xxx->hw_stats = jl2xxx_hw_stats;
+	jl2xxx->stats = kcalloc(jl2xxx->nstats, sizeof(u64), GFP_KERNEL);
+	if (!jl2xxx->stats) {
+        printk("cy: jl2xxx->stats fail\n");
+		return -ENOMEM;
+	}
+
+    printk("cy: jl2xxx_probe success\n");
+	return 0;
+}
+
+static int jl2xxx_config_init(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int ret;
+
+	if (!priv->static_inited) {
+#if (JLSEMI_DEBUG_INFO)
+		JLSEMI_PHY_MSG("jl2xxx_config_init_before:\n");
+		ret = jlsemi_phy_reg_print(phydev);
+		if (ret < 0)
+			return ret;
+#endif
+		ret = jl2xxx_static_op_init(phydev);
+		if (ret < 0)
+			return ret;
+#if (JLSEMI_DEBUG_INFO)
+		JLSEMI_PHY_MSG("jl2xxx_config_init_after:\n");
+		ret = jlsemi_phy_reg_print(phydev);
+		if (ret < 0)
+			return ret;
+#endif
+		priv->static_inited = JLSEMI_PHY_NOT_REENTRANT;
+	}
+
+	return 0;
+}
+
+static int jl2xxx_ack_interrupt(struct phy_device *phydev)
+{
+	int err;
+
+	err = jl2xxx_intr_ack_event(phydev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int jl2xxx_config_intr(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->intr.enable & JL2XXX_INTR_STATIC_OP_EN) {
+		err = jl2xxx_ack_interrupt(phydev);
+		if (err < 0)
+			return err;
+
+		err = jl2xxx_intr_static_op_set(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static int jl2xxx_read_status(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	bool fiber_mode;
+	int err;
+
+	if ((!priv->rxc_out.inited) &&
+	   (priv->rxc_out.enable & JL2XXX_RXC_OUT_STATIC_OP_EN) &&
+	   (priv->work_mode.mode == JL2XXX_MAC_SGMII_RGMII_MODE)) {
+		err = jlsemi_modify_paged_reg(phydev, JL2XXX_PAGE18,
+					      JL2XXX_WORK_MODE_REG,
+					      JL2XXX_WORK_MODE_MASK,
+					      priv->work_mode.mode);
+		if (err < 0)
+			return err;
+
+		err = jlsemi_soft_reset(phydev);
+		if (err < 0)
+			return err;
+		priv->rxc_out.inited = true;
+	}
+
+	if (priv->intr.enable & JL2XXX_INTR_STATIC_OP_EN) {
+		err = jl2xxx_ack_interrupt(phydev);
+		if (err < 0)
+			return err;
+	}
+
+	fiber_mode = jl2xxx_read_fiber_status(phydev);
+	if (fiber_mode)
+		return 0;
+
+	return genphy_read_status(phydev);
+}
+
+static int jl1xxx_config_aneg(struct phy_device *phydev)
+{
+	int ret;
+	ret = genphy_config_aneg(phydev);
+	printk("cy: jl1xxx_config_aneg %d\n", ret);
+	return ret;
+}
+
+static int jl2xxx_config_aneg(struct phy_device *phydev)
+{
+	u16 phy_mode;
+	int val;
+
+	val = jlsemi_read_paged(phydev, JL2XXX_PAGE18,
+				JL2XXX_WORK_MODE_REG);
+	phy_mode = val & JL2XXX_WORK_MODE_MASK;
+
+	if (((phy_mode == JL2XXX_FIBER_RGMII_MODE) ||
+	    (phy_mode == JL2XXX_UTP_FIBER_RGMII_MODE)))
+		return jl2xxx_config_aneg_fiber(phydev);
+
+	return genphy_config_aneg(phydev);
+}
+
+static int jl2xxx_suspend(struct phy_device *phydev)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	/* clear wol event */
+	if (priv->wol.enable & JL2XXX_WOL_STATIC_OP_EN) {
+		jlsemi_set_bits(phydev, JL2XXX_WOL_STAS_PAGE,
+				JL2XXX_WOL_STAS_REG, JL2XXX_WOL_EVENT);
+		jlsemi_clear_bits(phydev, JL2XXX_WOL_STAS_PAGE,
+				  JL2XXX_WOL_STAS_REG, JL2XXX_WOL_EVENT);
+	}
+	return genphy_suspend(phydev);
+}
+
+static int jl2xxx_resume(struct phy_device *phydev)
+{
+	return genphy_resume(phydev);
+}
+
+#if (JLSEMI_PHY_WOL)
+static void jl2xxx_get_wol(struct phy_device *phydev,
+			   struct ethtool_wolinfo *wol)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int wol_en;
+
+	if (priv->wol.ethtool) {
+		wol->supported = WAKE_MAGIC;
+		wol->wolopts = 0;
+
+		wol_en = jl2xxx_wol_dynamic_op_get(phydev);
+
+		if (wol_en)
+			wol->wolopts |= WAKE_MAGIC;
+	}
+}
+
+static int jl2xxx_set_wol(struct phy_device *phydev,
+			  struct ethtool_wolinfo *wol)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int err;
+
+	if (priv->wol.ethtool) {
+		if (wol->wolopts & WAKE_MAGIC) {
+			err = jl2xxx_wol_dynamic_op_set(phydev);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	return 0;
+}
+#endif
+
+#if (JL2XXX_PHY_TUNABLE)
+static int jl2xxx_get_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, void *data)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	switch (tuna->id) {
+	case ETHTOOL_PHY_FAST_LINK_DOWN:
+		if (priv->fld.ethtool)
+			return jl2xxx_fld_dynamic_op_get(phydev, data);
+		else
+			return 0;
+	case ETHTOOL_PHY_DOWNSHIFT:
+		if (priv->downshift.ethtool)
+			return jl2xxx_downshift_dynamic_op_get(phydev, data);
+		else
+			return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int jl2xxx_set_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, const void *data)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	switch (tuna->id) {
+	case ETHTOOL_PHY_FAST_LINK_DOWN:
+		if (priv->fld.ethtool)
+			return jl2xxx_fld_dynamic_op_set(phydev, data);
+		else
+			return 0;
+	case ETHTOOL_PHY_DOWNSHIFT:
+		if (priv->downshift.ethtool)
+			return jl2xxx_downshift_dynamic_op_set(phydev,
+							*(const u8 *)data);
+		else
+			return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+#endif
+
+#if (JL2XXX_GET_STAT)
+static u64 get_stat(struct phy_device *phydev, int i)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int val;
+
+	val = jlsemi_read_paged(phydev, priv->hw_stats[i].page,
+				priv->hw_stats[i].reg);
+	if (val < 0)
+		return U64_MAX;
+
+	val = val & priv->hw_stats[i].mask;
+	priv->stats[i] += val;
+
+	return priv->stats[i];
+}
+
+static void jl2xxx_get_stats(struct phy_device *phydev,
+			    struct ethtool_stats *stats, u64 *data)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int i;
+
+	if (!priv)
+		return;
+
+	for (i = 0; i < priv->nstats; i++)
+		data[i] = get_stat(phydev, i);
+}
+#endif
+
+#if (JL2XXX_GET_STRING)
+static void jl2xxx_get_strings(struct phy_device *phydev, u8 *data)
+{
+	struct jl2xxx_priv *priv = phydev->priv;
+	int i;
+
+	if (!priv)
+		return;
+
+	for (i = 0; i < priv->nstats; i++)
+		strlcpy(data + i * ETH_GSTRING_LEN,
+			priv->hw_stats[i].string, ETH_GSTRING_LEN);
+}
+#endif
+
+static void jl2xxx_remove(struct phy_device *phydev)
+{
+	struct device *dev = jlsemi_get_mdio(phydev);
+	struct jl2xxx_priv *priv = phydev->priv;
+
+	kfree(priv->stats);
+	if (priv)
+		devm_kfree(dev, priv);
+}
+
+static inline int jlsemi_aneg_done(struct phy_device *phydev)
+{
+	int retval = phy_read(phydev, MII_BMSR);
+
+	return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);
+}
+
+static int jl2xxx_aneg_done(struct phy_device *phydev)
+{
+	u16 phy_mode;
+	int val;
+
+	val = jlsemi_read_paged(phydev, JL2XXX_PAGE18,
+				JL2XXX_WORK_MODE_REG);
+	phy_mode = val & JL2XXX_WORK_MODE_MASK;
+
+	// fiber not an complite
+	if (((phy_mode == JL2XXX_FIBER_RGMII_MODE) ||
+	    (phy_mode == JL2XXX_UTP_FIBER_RGMII_MODE)))
+		return BMSR_ANEGCOMPLETE;
+
+	return jlsemi_aneg_done(phydev);
+}
+
+static struct phy_driver jlsemi_drivers[] = {
+	{
+		.phy_id			= JL1XXX_PHY_ID,
+		.phy_id_mask	= JLSEMI_PHY_ID_MASK,
+		.name			= DRIVER_NAME_100M,
+		/* PHY_BASIC_FEATURES */
+		.features		= PHY_BASIC_FEATURES,
+		.probe			= jl1xxx_probe,
+		//.config_intr	= jl1xxx_config_intr,
+		.read_status	= jl1xxx_read_status,
+		.config_init	= jl1xxx_config_init,
+		.config_aneg	= jl1xxx_config_aneg,
+		//.aneg_done		= jlsemi_aneg_done,
+		.private_proc	= jl1xxx_private_proc,
+		.suspend		= jl1xxx_suspend,
+		.resume			= jl1xxx_resume,
+		.remove			= jl1xxx_remove,
+#if (JLSEMI_PHY_WOL)
+		.get_wol		= jl1xxx_get_wol,
+		.set_wol		= jl1xxx_set_wol,
+#endif
+	},
+	{
+		.phy_id			= JL2XXX_PHY_ID,
+		.phy_id_mask	= JLSEMI_PHY_ID_MASK,
+		.name			= DRIVER_NAME_1000M,
+		/* PHY_BASIC_FEATURES */
+		.features		= PHY_GBIT_FEATURES,
+		.probe			= jl2xxx_probe,
+		.config_intr	= jl2xxx_config_intr,
+		.read_status	= jl2xxx_read_status,
+		.config_init	= jl2xxx_config_init,
+		.config_aneg	= jl2xxx_config_aneg,
+		//.aneg_done		= jl2xxx_aneg_done,
+		.suspend		= jl2xxx_suspend,
+		.resume			= jl2xxx_resume,
+		.remove			= jl2xxx_remove,
+#if (JLSEMI_PHY_WOL)
+		.get_wol		= jl2xxx_get_wol,
+		.set_wol		= jl2xxx_set_wol,
+#endif
+#if (JL2XXX_PHY_TUNABLE)
+		.get_tunable	= jl2xxx_get_tunable,
+		.set_tunable	= jl2xxx_set_tunable,
+#endif
+#if (JL2XXX_GET_STAT)
+		.get_stats		= jl2xxx_get_stats,
+#endif
+#if (JL2XXX_GET_STRING)
+		.get_strings	= jl2xxx_get_strings,
+#endif
+	},
+};
+
+module_jlsemi_driver(jlsemi_drivers);
+
+static struct mdio_device_id __maybe_unused jlsemi_tbl[] = {
+	{JL1XXX_PHY_ID, JLSEMI_PHY_ID_MASK},
+	{JL2XXX_PHY_ID, JLSEMI_PHY_ID_MASK},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(mdio, jlsemi_tbl);
diff --git a/lynq/R306_MTN/ap/project/zx297520v3/prj_cpe/config/normal/config.linux b/lynq/R306_MTN/ap/project/zx297520v3/prj_cpe/config/normal/config.linux
new file mode 100755
index 0000000..6d9ab31
--- /dev/null
+++ b/lynq/R306_MTN/ap/project/zx297520v3/prj_cpe/config/normal/config.linux
@@ -0,0 +1,2097 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.4.110 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="DEMO"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_IRQ_DOMAIN=y
+# CONFIG_IRQ_DOMAIN_DEBUG is not set
+CONFIG_IRQ_FORCED_THREADING=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_RCU_BOOST=y
+CONFIG_RCU_BOOST_PRIO=1
+CONFIG_RCU_BOOST_DELAY=500
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+# CONFIG_SHMEM is not set
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_PRIMA2 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_PICOXCELL is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_VT8500 is not set
+# CONFIG_ARCH_ZYNQ is not set
+# CONFIG_ARCH_ZX297510 is not set
+# CONFIG_ARCH_ZX297520V2 is not set
+CONFIG_ARCH_ZX297520V3=y
+# CONFIG_GPIO_PCA953X is not set
+
+#
+# System MMU
+#
+CONFIG_ZX29_TIMER_HZ=200
+CONFIG_ZX_RAM_CONSOLE=y
+CONFIG_ZX_PM_DEBUG=y
+# CONFIG_ZX_PM_DEBUG_TIME is not set
+CONFIG_AXI_FREQ=y
+
+#
+# ZX297520V3 Board Type
+#
+# CONFIG_ARCH_ZX297520V3_EVB is not set
+# CONFIG_ARCH_ZX297520V3_CPE_SWITCH is not set
+CONFIG_ARCH_ZX297520V3_CPE=y
+# CONFIG_ARCH_ZX297520V3_MDL is not set
+# CONFIG_ARCH_ZX297520V3_MIFI is not set
+# CONFIG_ARCH_ZX297520V3_POC is not set
+# CONFIG_ARCH_ZX297520V3_PHONE is not set
+# CONFIG_ARCH_ZX297520V3_WATCH is not set
+# CONFIG_ARCH_ZX297520V3_FPGA is not set
+# CONFIG_MIN_VERSION is not set
+CONFIG_MODEM_CODE_IS_MAPPING=y
+CONFIG_PLAT_ZTE=y
+CONFIG_STACK_SIZE=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
+CONFIG_CPU_HAS_PMU=y
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_751472=y
+CONFIG_ARM_ERRATA_754322=y
+# CONFIG_ARM_ERRATA_775420 is not set
+# CONFIG_FIQ_DEBUGGER is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_RT_BASE=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT__LL is not set
+# CONFIG_PREEMPT_RTB is not set
+CONFIG_PREEMPT_RT_FULL=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=200
+CONFIG_THUMB2_KERNEL=y
+CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11=y
+CONFIG_ARM_ASM_UNIFIED=y
+CONFIG_AEABI=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+CONFIG_RAMDUMP=y
+CONFIG_RAMDUMP_TRANS_SERVER=y
+# CONFIG_TRANS_WITH_COLLECT is not set
+CONFIG_RAMDUMP_ABNORMAL_EXIT_TASK=y
+# CONFIG_KERNEL_GLOBAL_DEBUG is not set
+# CONFIG_MEM_TRACKER is not set
+# CONFIG_KMALLOC_TRACKER is not set
+CONFIG_LIMIT_PAGE_CACHE=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+# CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART is not set
+# CONFIG_THREAD_DEBUG is not set
+# CONFIG_INT_DEBUG is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x10000000
+CONFIG_ZBOOT_ROM_BSS=0x20040000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_CMDLINE="root=/dev/mtdblock5 ro rootfstype=jffs2"
+# CONFIG_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_CMDLINE_EXTEND=y
+# CONFIG_CMDLINE_FORCE is not set
+CONFIG_SYSTEM_NORMAL=y
+# CONFIG_SYSTEM_RECOVERY is not set
+# CONFIG_SYSTEM_CAP is not set
+CONFIG_CPPS_KO=y
+# CONFIG_BOOT_WITHOUT_UBOOT is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+
+#
+# ARM CPU frequency scaling drivers
+#
+# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HAS_WAKELOCK=y
+CONFIG_WAKELOCK=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=100
+# CONFIG_PM_WAKELOCKS_GC is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_CAN_PM_TRACE=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_SUSPEND_TIME=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_NETCTL=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+CONFIG_IP_MULTIPLE_TABLES=y
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+# CONFIG_IP_PIMSM_V1 is not set
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+CONFIG_INET_ESP=y
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+# CONFIG_INET6_AH is not set
+CONFIG_INET6_ESP=y
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_ANDROID_PARANOID_NETWORK=y
+CONFIG_NET_ACTIVITY_STATS=y
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=y
+CONFIG_NETFILTER_NETLINK_ACCT=y
+CONFIG_NETFILTER_NETLINK_QUEUE=y
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+CONFIG_NF_CONNTRACK=y
+CONFIG_WEBSTR_FILTER=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_PROCFS=y
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+# CONFIG_NF_CONNTRACK_TIMEOUT is not set
+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
+# CONFIG_NF_CT_PROTO_DCCP is not set
+CONFIG_NF_CT_PROTO_GRE=y
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_SNMP is not set
+CONFIG_NF_CONNTRACK_PPTP=y
+# CONFIG_NF_CONNTRACK_SANE is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
+# CONFIG_NETFILTER_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+CONFIG_NETFILTER_XT_MARK=y
+# CONFIG_NETFILTER_XT_CONNMARK is not set
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
+CONFIG_NETFILTER_XT_TARGET_DSCP=y
+CONFIG_NETFILTER_XT_TARGET_HL=y
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
+# CONFIG_NETFILTER_XT_TARGET_LOG is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+# CONFIG_NETFILTER_XT_MATCH_ECN is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA2 is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_SET is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_RPFILTER is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_REJECT_SKERR is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=y
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_TSP_FASTBIH=y
+CONFIG_NF_NAT_PROTO_GRE=y
+# CONFIG_NF_NAT_FTP is not set
+# CONFIG_NF_NAT_IRC is not set
+CONFIG_NF_NAT_TFTP=y
+# CONFIG_NF_NAT_AMANDA is not set
+CONFIG_NF_NAT_PPTP=y
+# CONFIG_NF_NAT_H323 is not set
+# CONFIG_NF_NAT_SIP is not set
+CONFIG_IP_NF_MANGLE=y
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+# CONFIG_IP_NF_TARGET_ECN is not set
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_CONNTRACK_IPV6=y
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=y
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+# CONFIG_IP6_NF_MATCH_HL is not set
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+# CONFIG_IP6_NF_MATCH_MH is not set
+# CONFIG_IP6_NF_MATCH_RPFILTER is not set
+# CONFIG_IP6_NF_MATCH_RT is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_FILTER=y
+# CONFIG_IP6_NF_TARGET_REJECT is not set
+CONFIG_IP6_NF_MANGLE=y
+# CONFIG_IP6_NF_RAW is not set
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE_EBT_T_FILTER=y
+# CONFIG_BRIDGE_EBT_T_NAT is not set
+# CONFIG_BRIDGE_EBT_802_3 is not set
+# CONFIG_BRIDGE_EBT_AMONG is not set
+# CONFIG_BRIDGE_EBT_ARP is not set
+CONFIG_BRIDGE_EBT_IP=y
+# CONFIG_BRIDGE_EBT_IP6 is not set
+# CONFIG_BRIDGE_EBT_LIMIT is not set
+CONFIG_BRIDGE_EBT_MARK=y
+# CONFIG_BRIDGE_EBT_PKTTYPE is not set
+# CONFIG_BRIDGE_EBT_STP is not set
+# CONFIG_BRIDGE_EBT_VLAN is not set
+# CONFIG_BRIDGE_EBT_ARPREPLY is not set
+# CONFIG_BRIDGE_EBT_DNAT is not set
+CONFIG_BRIDGE_EBT_MARK_T=y
+# CONFIG_BRIDGE_EBT_REDIRECT is not set
+# CONFIG_BRIDGE_EBT_SNAT is not set
+# CONFIG_BRIDGE_EBT_LOG is not set
+# CONFIG_BRIDGE_EBT_ULOG is not set
+# CONFIG_BRIDGE_EBT_NFLOG is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+CONFIG_ATM=y
+# CONFIG_ATM_CLIP is not set
+# CONFIG_ATM_LANE is not set
+# CONFIG_ATM_BR2684 is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=y
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=y
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+CONFIG_NET_SCHED=y
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_HFSC=y
+CONFIG_NET_SCH_ATM=y
+CONFIG_NET_SCH_PRIO=y
+# CONFIG_NET_SCH_MULTIQ is not set
+CONFIG_NET_SCH_RED=y
+# CONFIG_NET_SCH_SFB is not set
+CONFIG_NET_SCH_SFQ=y
+CONFIG_NET_SCH_TEQL=y
+CONFIG_NET_SCH_TBF=y
+CONFIG_NET_SCH_GRED=y
+CONFIG_NET_SCH_DSMARK=y
+CONFIG_NET_SCH_NETEM=y
+CONFIG_NET_SCH_DRR=y
+# CONFIG_NET_SCH_MQPRIO is not set
+# CONFIG_NET_SCH_CHOKE is not set
+# CONFIG_NET_SCH_QFQ is not set
+CONFIG_NET_SCH_INGRESS=y
+# CONFIG_NET_SCH_PLUG is not set
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=y
+CONFIG_NET_CLS_TCINDEX=y
+CONFIG_NET_CLS_ROUTE4=y
+CONFIG_NET_CLS_FW=y
+CONFIG_NET_CLS_U32=y
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=y
+CONFIG_NET_CLS_RSVP6=y
+# CONFIG_NET_CLS_FLOW is not set
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+# CONFIG_NET_EMATCH_CMP is not set
+# CONFIG_NET_EMATCH_NBYTE is not set
+CONFIG_NET_EMATCH_U32=y
+# CONFIG_NET_EMATCH_META is not set
+CONFIG_NET_EMATCH_TEXT=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=y
+# CONFIG_GACT_PROB is not set
+# CONFIG_NET_ACT_MIRRED is not set
+CONFIG_NET_ACT_IPT=y
+# CONFIG_NET_ACT_NAT is not set
+CONFIG_NET_ACT_PEDIT=y
+# CONFIG_NET_ACT_SIMP is not set
+CONFIG_NET_ACT_SKBEDIT=y
+# CONFIG_NET_ACT_CSUM is not set
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+CONFIG_BQL=y
+CONFIG_HAVE_BPF_JIT=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_DEBUGFS is not set
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+# CONFIG_CFG80211_ALLOW_RECONNECT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_PM=y
+CONFIG_RFKILL_LEDS=y
+# CONFIG_RFKILL_INPUT is not set
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_SYNC is not set
+CONFIG_ZX_PM_SUSPEND=y
+CONFIG_ZX_AUTOSLEEP=y
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+CONFIG_PARTS_GUARD=y
+CONFIG_MTD_ADAPTER=y
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_GPIO_ADDR is not set
+CONFIG_MTD_PLATRAM=y
+# CONFIG_MTD_LATCH_ADDR is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_DENALI is not set
+CONFIG_MTD_ZXIC_SPIFC=y
+CONFIG_NAND_INTERFACE_LINUX=y
+# CONFIG_MTD_NAND_GPIO is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_SPI_NOR is not set
+
+#
+# LPDDR flash memory drivers
+#
+CONFIG_MTD_LPDDR=y
+CONFIG_MTD_QINFO_PROBE=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=3
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_SENSORS_AK8975 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_UID_STAT is not set
+# CONFIG_BMP085 is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_WL127X_RFKILL is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_MII is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+CONFIG_TUN=y
+# CONFIG_VETH is not set
+CONFIG_ATM_DRIVERS=y
+# CONFIG_ATM_DUMMY is not set
+# CONFIG_ATM_TCP is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_ZTE=y
+CONFIG_ZX29_GMAC=y
+# CONFIG_NET_ZX29_GMAC is not set
+CONFIG_PHYLIB=y
+# CONFIG_NET_ZX29_GMAC_PHY is not set
+# CONFIG_NET_ZX29_GMAC_SWITCH is not set
+CONFIG_JLSEMI_PHY=y
+
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_MPPE=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPPOATM is not set
+CONFIG_PPPOE=y
+# CONFIG_PPPOLAC is not set
+# CONFIG_PPPOPNS is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=y
+CONFIG_WLAN=y
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_RTL_NONE is not set
+# CONFIG_RTL8192CD is not set
+# CONFIG_RTL8189E is not set
+# CONFIG_MIFI_WIFI is not set
+# CONFIG_RTL_WIFI is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_MWIFIEX is not set
+# CONFIG_RDAWFMAC is not set
+CONFIG_RTL8192CD=y
+CONFIG_RTL_WIFI=y
+CONFIG_RTL_92E_SUPPORT=y
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_7510_DDR_AP_NET is not set
+CONFIG_NET_ZX29_AT=y
+CONFIG_PS_NET=y
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_KEYRESET is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_OMAP4 is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_ZX297510 is not set
+CONFIG_KEYBOARD_ZX_INT=y
+# CONFIG_KEYBOARD_ZX_4x4 is not set
+# CONFIG_KEYBOARD_ZX_5x6 is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=5
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_N_GSM=y
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVMEM=y
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_SERIAL_ZX297502_UART is not set
+# CONFIG_SERIAL_ZX297510_UART is not set
+CONFIG_SERIAL_ZX29_UART=y
+CONFIG_SERIAL_ZX29_UART_CONSOLE=y
+CONFIG_UART_CONSOLE_ID=1
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_DCC_TTY is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_MUX is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+CONFIG_I2C_ZX29=y
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+CONFIG_SPI_ZX29=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+CONFIG_GPIO_ZX29=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MCP23S08 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_SUPPLY_DEBUG=y
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_SBS is not set
+# CONFIG_BATTERY_BQ24165 is not set
+# CONFIG_CHARGER_ZX234502 is not set
+# CONFIG_CHARGER_AW3215 is not set
+# CONFIG_CHARGER_SGM40561 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_BATTERY_ANDROID is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_LP8727 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_SMB347 is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_ZX29_WATCHDOG=y
+CONFIG_ZX29_WDT_TEST=m
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+CONFIG_MFD_ZX234290=y
+CONFIG_MFD_ZX234290_I2C=y
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_S5M_CORE is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_ION is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_DWC_OTG_USB=y
+CONFIG_DWC_DEVICE_ONLY=y
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_OTG_WAKELOCK is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_MMC_ZX29=y
+CONFIG_MMC_ZX29_PLTFM=y
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_LM3530 is not set
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP5523 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_PCA9633 is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+# CONFIG_LEDS_RENESAS_TPU is not set
+# CONFIG_LEDS_TCA6507 is not set
+# CONFIG_LEDS_ZX297520UFI is not set
+# CONFIG_LEDS_OT200 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=y
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_SWITCH is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_ZX297510 is not set
+CONFIG_RTC_ZX234290=y
+CONFIG_DMADEVICES=y
+CONFIG_DMADEVICES_DEBUG=y
+# CONFIG_DMADEVICES_VDEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_ZX29_DMA=y
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+CONFIG_STAGING=y
+# CONFIG_ECHO is not set
+# CONFIG_RTLLIB is not set
+# CONFIG_IIO is not set
+# CONFIG_ZSMALLOC is not set
+# CONFIG_FT1000 is not set
+
+#
+# Speakup console speech
+#
+# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
+# CONFIG_STAGING_MEDIA is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID is not set
+# CONFIG_PHONE is not set
+
+#
+# ZX297510 USB PROXY
+#
+CONFIG_USB_PROXY=y
+
+#
+# ZX297520 volte driver
+#
+# CONFIG_VOLTE_DRV is not set
+
+#
+# ZX297520V3 camera driver
+#
+# CONFIG_CAMERA_DRV is not set
+#
+# ZX297520 audiomix driver
+#
+# CONFIG_AUDIOMIX_DRV is not set
+CONFIG_CLKDEV_LOOKUP=y
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_IOMMU_SUPPORT=y
+
+#
+# Remoteproc drivers (EXPERIMENTAL)
+#
+
+#
+# Rpmsg drivers (EXPERIMENTAL)
+#
+# CONFIG_VIRT_DRIVERS is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_RPM_ZX29 is not set
+CONFIG_TSC_ZX29=y
+CONFIG_DDR_ZX29=m
+# CONFIG_OS_EXTEND is not set
+# CONFIG_SI3217X is not set
+# CONFIG_SI3218X is not set
+CONFIG_CPNV=y
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+# CONFIG_JFFS2_ZLIB is not set
+CONFIG_JFFS2_LZO=y
+# CONFIG_JFFS2_LZMA is not set
+# CONFIG_JFFS2_RTIME is not set
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_UBIFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT=""
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+CONFIG_HEADERS_CHECK=y
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR_NMI is not set
+# CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BUILD_DOCSRC is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_RODATA=y
+# CONFIG_DEBUG_RODATA_TEST is not set
+# CONFIG_DEBUG_LL is not set
+CONFIG_ACCURATE_CPU_PERCENT=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+# CONFIG_VERIFY_APP_IN_KERNEL is not set
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=y
+CONFIG_TEXTSEARCH_BM=y
+CONFIG_TEXTSEARCH_FSM=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
+CONFIG_VOLTE_DRV=y
+CONFIG_AMR_DRV=y
+CONFIG_SLIC_TW=y
+CONFIG_CP_USE_SOFT_DTMF_DETECT=y
+CONFIG_VOICE_DRV=y
+# CONFIG_VOICE_BUFFER_DRV is not set
\ No newline at end of file
diff --git a/lynq/R306_MTN/ap/project/zx297520v3/prj_cpe/fs/normal/rootfs/etc_ro/default/default_parameter_user b/lynq/R306_MTN/ap/project/zx297520v3/prj_cpe/fs/normal/rootfs/etc_ro/default/default_parameter_user
new file mode 100755
index 0000000..a3c4e3e
--- /dev/null
+++ b/lynq/R306_MTN/ap/project/zx297520v3/prj_cpe/fs/normal/rootfs/etc_ro/default/default_parameter_user
@@ -0,0 +1,469 @@
+apn_auto_config=CMCC($)cmnet($)manual($)*99#($)pap($)($)($)IP($)auto($)($)auto($)($)
+APN_config0=Default($)Default($)manual($)($)($)($)($)IP($)auto($)($)auto($)($)
+APN_config1=
+APN_config2=
+APN_config3=
+APN_config4=
+APN_config5=
+APN_config6=
+APN_config7=
+APN_config8=
+APN_config9=
+apn_index=0
+apn_mode=auto
+at_snap_flag=3
+at_wifi_mac=0
+auto_apn_index=0
+cid_reserved=0
+clear_pb_when_restore=no
+clear_sms_when_restore=no
+default_apn=3gnet
+ipv6_APN_config1=
+ipv6_APN_config2=
+ipv6_APN_config3=
+ipv6_APN_config4=
+ipv6_APN_config5=
+ipv6_APN_config6=
+ipv6_APN_config7=
+ipv6_APN_config8=
+ipv6_APN_config9=
+m_profile_name=Internux
+need_init_modem=yes
+net_select=NETWORK_auto
+pdp_type=IP
+ppp_apn=
+max_reconnect_time=3000000
+pppd_auth=noauth
+ppp_auth_mode=none
+ppp_passwd=
+ppp_pdp_type=
+ppp_username=
+ipv6_ppp_auth_mode=none
+ipv6_ppp_passwd=
+ipv6_ppp_username=
+pre_mode=
+prefer_dns_manual=0.0.0.0
+standby_dns_manual=0.0.0.0
+wan_apn=internet
+wan_dial=
+cta_test=0
+safecare_enbale=1
+safecare_hostname=mob.3gcare.cn
+safecare_registed_imei=
+safecare_registed_iccid=
+safecare_contimestart1=
+safecare_contimestart2=
+safecare_contimestart3=
+safecare_contimestop1=
+safecare_contimestop2=
+safecare_contimestop3=
+safecare_contimeinterval=
+safecare_mobsite=http://mob.3gcare.cn
+safecare_chatsite=
+safecare_platno=
+safecare_mobilenumber=
+safecare_version=
+ethwan_dns_mode=auto
+pswan_dns_mode=auto
+wifiwan_dns_mode=auto
+ethwan_ipv6_dns_mode=auto
+wifiwan_ipv6_dns_mode=auto
+pswan_ipv6_dns_mode=auto
+admin_Password=admin
+psw_changed=
+alg_ftp_enable=0
+alg_sip_enable=0
+blc_wan_auto_mode=AUTO_PPP
+blc_wan_mode=AUTO
+br_ipchange_flag=
+br_node=usblan0
+clat_fake_subnet=192.0.168.0
+clat_frag_collect_timeout=300
+clat_local_mapping_timeout=300
+clat_mapping_record_timeout=3000
+clat_query_server_port=1464
+DefaultFirewallPolicy=0
+dev_coexist=0
+dhcpDns=192.168.0.1
+dhcpEnabled=1
+dhcpEnd=192.168.0.200
+dhcpLease_hour=24
+dhcpStart=192.168.0.100
+dhcpv6stateEnabled=0
+dhcpv6statelessEnabled=1
+dhcpv6statePdEnabled=0
+dial_mode=auto_dial
+DMZEnable=0
+DMZIPAddress=
+dns_extern=
+ipv6_dns_extern=
+eth_act_type=
+eth_type=auto
+ethlan=eth0
+ethwan=eth0
+ethwan_dialmode=auto
+ethwan_mode=auto
+ethwan_priority=3
+fast_usb=usblan0
+fastnat_level=2
+IPPortFilterEnable=0
+IPPortFilterRules_0=
+IPPortFilterRules_1=
+IPPortFilterRules_2=
+IPPortFilterRules_3=
+IPPortFilterRules_4=
+IPPortFilterRules_5=
+IPPortFilterRules_6=
+IPPortFilterRules_7=
+IPPortFilterRules_8=
+IPPortFilterRules_9=
+IPPortFilterRulesv6_0=
+IPPortFilterRulesv6_1=
+IPPortFilterRulesv6_2=
+IPPortFilterRulesv6_3=
+IPPortFilterRulesv6_4=
+IPPortFilterRulesv6_5=
+IPPortFilterRulesv6_6=
+IPPortFilterRulesv6_7=
+IPPortFilterRulesv6_8=
+IPPortFilterRulesv6_9=
+ipv4_fake_subnet=192.0.0.0
+ipv6_fake_subnet=2016::1
+lan_ipaddr=192.168.0.1
+lan_name=br0
+lan_netmask=255.255.255.0
+LanEnable=1
+mac_ip_list=
+mgmt_quicken_power_on=0
+mtu=1400
+natenable=
+dosenable=0
+need_jilian=1
+nofast_port=21+22+23+25+53+67+68+69+110+115+123+443+500+1352+1723+1990+1991+1992+1993+1994+1995+1996+1997+1998+4500+5060
+nv_save_interval=300
+path_conf=/etc_rw
+path_ro=/etc_ro
+path_log=/var/log/
+path_sh=/sbin
+path_tmp=/tmp
+permit_gw=
+permit_ip6=
+permit_nm=255.255.255.0
+PortForwardEnable=0
+PortForwardRules_0=
+PortForwardRules_1=
+PortForwardRules_2=
+PortForwardRules_3=
+PortForwardRules_4=
+PortForwardRules_5=
+PortForwardRules_6=
+PortForwardRules_7=
+PortForwardRules_8=
+PortForwardRules_9=
+PortMapEnable=0
+PortMapRules_0=
+PortMapRules_1=
+PortMapRules_2=
+PortMapRules_3=
+PortMapRules_4=
+PortMapRules_5=
+PortMapRules_6=
+PortMapRules_7=
+PortMapRules_8=
+PortMapRules_9=
+ppp_name=ppp0
+pppoe_password=
+pppoe_username=
+ps_ext1=usblan0
+ps_ext2=usblan0
+ps_ext3=usblan0
+ps_ext4=usblan0
+ps_ext5=usblan0
+ps_ext6=usblan0
+ps_ext7=usblan0
+ps_ext8=usblan0
+pswan=wan
+pswan_mode=pdp
+pswan_priority=1
+RemoteManagement=0
+rj45_plugstate_path=/sys/gmac/gmacconfig/eth_phy_state
+rootdev_friendlyname=DEMO-UPnP
+rootdev_manufacturer=DEMO
+rootdev_modeldes=XXX
+rootdev_modelname=XXX
+os_url=http://www.demo.com
+serialnumber=See-IMEI
+static_dhcp_enable=1
+static_ethwan_gw=
+static_ethwan_ip=
+static_ethwan_nm=
+static_ethwan_pridns=
+static_ethwan_secdns=
+static_wifiwan_ipaddr=
+static_wifiwan_netmask=
+static_wifiwan_gateway=
+wifiwan_pridns_manual=
+wifiwan_secdns_manual=
+static_wan_gateway=0.0.0.0
+static_wan_ipaddr=0.0.0.0
+static_wan_netmask=0.0.0.0
+static_wan_primary_dns=0.0.0.0
+static_wan_secondary_dns=0.0.0.0
+swlanstr=sw0_lan
+swvlan=sw0
+swwanstr=sw0_wan
+tc_downlink=
+tc_uplink=
+tc_local=1310720
+tc_enable=0
+time_limited=
+time_to_2000_when_restore=yes
+upnpEnabled=0
+usblan=usblan0
+WANPingFilter=0
+websURLFilters=
+wifiwan_priority=2
+DDNS=
+DDNS_Enable=0
+DDNSAccount=
+DDNSPassword=
+DDNSProvider=
+iccidPrevious=
+imeiPrevious=
+registerFlag=0
+registeredRound=
+secsEveryRound=1
+secsEveryTime=1
+regver=4.0
+meid=
+uetype=1
+LocalDomain=m.home
+data_volume_alert_percent=
+data_volume_limit_size=
+data_volume_limit_switch=0
+data_volume_limit_unit=0
+flux_day_total=0
+flux_last_day=
+flux_last_month=
+flux_last_year=
+flux_month_total=0
+flux_set_day=
+flux_set_month=
+flux_set_year=
+monthly_rx_bytes=0
+monthly_time=0
+monthly_tx_bytes=0
+MonthlyConTime_Last=
+dm_nextpollingtime=
+fota_allowRoamingUpdate=0
+fota_dl_pkg_size=0
+fota_update_flag=
+fota_updateIntervalDay=15
+fota_upgrade_result=
+fota_version_delta_id=
+fota_version_delta_url=
+fota_pkg_total_size=0
+fota_version_file_size=
+fota_version_md5sum=
+fota_version_name=
+fota_need_user_confirm_update=0
+fota_need_user_confirm_download=1
+fota_version_force_install=0
+polling_nexttime=0
+pwron_auto_check=1
+fota_updateMode=1
+fota_test_mode=0
+fota_pkg_downloaded=0
+fota_upgrade_result_internal=
+mmi_battery_voltage_line=3090+3300+3450+3490+3510+3540+3550+3570+3580+3600+3620+3650+3670+3710+3740+3780+3850+3900+3950+4000+4060
+mmi_fast_poweron=
+mmi_led_mode=sleep_mode
+mmi_new_sms_blink_flag=1
+mmi_show_pagetab=page1+page2+page3
+mmi_showmode=led
+mmi_task_tab=net_task+ctrl_task+wifi_task+traffic_task+key_task+battery_task+tip_task+tipwps_task+tipwifistation_task+tipfota_task+tipwps_task+tipnetconnect_task+wificode_task+ssid_task+sms_task
+mmi_temp_voltage_line=951+1201+1692+1736
+mmi_use_protect=
+mmi_use_wifi_usernum=1
+leak_full_panic=
+leak_list_max=
+leak_set_flag=
+monitor_period=300
+netinf_flag=
+skb_all_max=
+skb_data_max=
+skb_fromcp_max=
+skb_max_fail=
+skb_max_panic=
+skb_size_max=
+skb_tocp_max=
+sntp_default_ip=134.170.185.211;131.107.13.100;202.112.31.197;202.112.29.82;202.112.10.36;ntp.gwadar.cn;ntp-sz.chl.la;dns.sjtu.edu.cn;news.neu.edu.cn;dns1.synet.edu.cn;time-nw.nist.gov;pool.ntp.org;europe.pool.ntp.org
+sntp_dst_enable=0
+sntp_other_server0=
+sntp_other_server1=
+sntp_other_server2=
+sntp_server0=time-nw.nist.gov
+sntp_server1=pool.ntp.org
+sntp_server2=europe.pool.ntp.org
+sntp_sync_select_interval_time=30
+sntp_time_set_mode=auto
+sntp_timezone=CST-8
+sntp_timezone_index=0
+assert_errno=
+comm_logsize=16384
+cr_inner_version=V1.0.0B08
+cr_version=V1.0.0B01
+hw_version=PCBMF29S2V1.0.0
+TURNOFF_CHR_NUM=
+watchdog_app=0
+HTTP_SHARE_FILE=
+HTTP_SHARE_STATUS=
+HTTP_SHARE_WR_AUTH=readWrite
+ipv6_pdp_type=
+ipv6_wan_apn=
+Language=zh-cn
+manual_time_day=
+manual_time_hour=
+manual_time_minute=
+manual_time_month=
+manual_time_second=
+manual_time_year=
+sdcard_mode_option=0
+AccessControlList0=
+AccessPolicy0=0
+ACL_mode=0
+AuthMode=WPA2PSK
+Channel=0
+closeEnable=0
+closeTime=
+CountryCode=CN
+DefaultKeyID=0
+DtimPeriod=1
+EncrypType=AES
+EX_APLIST=
+EX_APLIST1=
+EX_AuthMode=
+EX_DefaultKeyID=
+EX_EncrypType=
+EX_mac=
+EX_SSID1=CPE_
+EX_WEPKEY=
+EX_wifi_profile=
+EX_WPAPSK1=
+FragThreshold=2346
+HideSSID=0
+HT_GI=1
+Key1Str1=12345
+Key2Str1=
+Key3Str1=
+Key4Str1=
+Key1Type=1
+Key2Type=
+Key3Type=
+Key4Type=
+m_AuthMode=WPA2PSK
+m_DefaultKeyID=
+m_EncrypType=AES
+m_HideSSID=0
+m_Key1Str1=1234
+m_Key2Str1=
+m_Key3Str1=
+m_Key4Str1=
+m_Key1Type=1
+m_Key2Type=
+m_Key3Type=
+m_Key4Type=
+m_MAX_Access_num=0
+m_NoForwarding=
+m_show_qrcode_flag=0
+m_SSID=CPE_
+m_ssid_enable=0
+m_wapiType=
+m_wifi_mac=901D45692A5C
+m_WPAPSK1_aes=
+m_WPAPSK1_encode=MTIzNDU2Nzg=
+MAX_Access_num=32
+MAX_Access_num_bak=32
+NoForwarding=0
+openEnable=0
+openTime=
+operater_ap=
+RekeyInterval=3600
+RTSThreshold=2347
+show_qrcode_flag=0
+Sleep_interval=10
+ssid_write_flag=0
+SSID1=CPE_
+tsw_sleep_time_hour=
+tsw_sleep_time_min=
+tsw_wake_time_hour=
+tsw_wake_time_min=
+wapiType=
+wifi_11n_cap=1
+wifi_band=b
+wifi_coverage=long_mode
+wifi_hostname_black_list=
+wifi_hostname_white_list=
+wifi_mac=901D45692A5B
+wifi_mac_black_list=
+wifi_mac_white_list=
+wifi_profile=
+wifi_profile1=
+wifi_profile2=
+wifi_profile3=
+wifi_profile4=
+wifi_profile5=
+wifi_profile6=
+wifi_profile7=
+wifi_profile8=
+wifi_profile9=
+wifi_profile_num=0
+wifi_root_dir=
+wifi_sta_connection=0
+wifi_wps_index=1
+wifiEnabled=1
+wifilan=wlan0-va0
+wifilan2=wlan0-va1
+WirelessMode=4
+WPAPSK1_aes=
+WPAPSK1_encode=MTIzNDU2Nzg=
+wps_mode=
+WPS_SSID=
+WscModeOption=0
+monitor_apps=
+at_netdog=
+autorspchannel_list=all
+soctime_switch=0
+uart_control=0
+uart_ctstrs_enable=
+uart_softcontrol_enable=
+uart_wakeup_enable=1
+special_cmd_list=$MYNETREAD
+##为入网入库芯片认证版本添åŠ?begin
+atcmd_stream1=AT+ZSET="w_instrument",1
+atcmd_stream2=AT^SYSCONFIG=24,0,1,2
+atcmd_stream3=AT+ZSET="csiiot",2
+atcmd_stream4=AT+ZSET="dlparaflg",0
+atcmd_stream5=AT+ZSET="MTNET_TEST",1;AT+ZGAAT=0;AT+ZSET="CMCC_TEST",1;AT+ZSET="LTE_INFO",6348;AT+ZSET="VOICE_SUPPORT",1;AT+ZSET="FDD_RELEASE",7;AT+ZSET="LTE_RELEASE",1;AT+ZSET="UE_PS_RELEASE",5;AT+ZSET="QOS_RELEASE",4;AT+ZSET="TEBS_THRESHOLD",0
+atcmd_stream6=AT+ZSET="MTNET_TEST",1;AT+ZGAAT=0;AT+ZSET="LTE_INFO",6348;AT+ZSET="VOICE_SUPPORT",1;AT+ZSET="FDD_RELEASE",7;AT+ZSET="LTE_RELEASE",1;AT+ZSET="UE_PS_RELEASE",5;AT+ZSET="QOS_RELEASE",4;AT+ZSET="TEBS_THRESHOLD",0;AT+ZSET="IGNORE_SECURITY_SUPPORT",0;AT+ZSET="csifilter",0;AT+ZSET="csrhobandflg",0;AT+ZSET="dlparaflg",1;AT+ZSET="csiup",1;AT+ZSET="rfparaflag",0,0,1,0;AT+ZSET="csiiot",1;AT+ZSET="EXCEPT_RESET",0;AT+ZSET="ISIM_SUPPORT",1;AT+ZIMSTEST="MTNET_TEST",1;AT+ZSET="MANUAL_SEARCH",0
+##为入网入库芯片认证版本添åŠ?end
+#for audio ctrl 
+audio_priority=0123
+customer_type=
+debug_mode=
+cpIndCmdList=+ZMMI+ZURDY+ZUSLOT+ZICCID^MODE+ZPBIC+ZMSRI+CREG+CEREG+CGREG+CGEV
+zephyr_filter_ip=
+wait_timeout=2
+sntp_static_server0=time-nw.nist.gov
+sntp_static_server1=pool.ntp.org
+sntp_static_server2=europe.pool.ntp.org
+vsim_bin_path=/mnt/userdata/vSim.bin
+at_select_timeout=
+mtnet_test_mcc=
+at_atv=
+at_atq=
+at_at_d=
+base_ip_on_mac=0
+dbinfo=
+quick_dial=1
+xlat_enable=0