[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, ¶m);
+
+ 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