summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2015-09-17 19:45:22 +0200
committerWaldemar Brodkorb <wbx@openadk.org>2015-09-17 19:45:38 +0200
commit13c60d6c3c2989ff18a8964573cf8c5ebc56b57d (patch)
treeaa314e80df2e3bad6223e5fe244905ba090d2d07
parentf1fc0a7a49e01b52339a6c2a89efa6144da14461 (diff)
add 4.1.x patches for mikrotik-rb4xx, finetune mini.config, drivers should go into target/linux/config
-rw-r--r--target/config/Config.in.endian.choice1
-rw-r--r--target/linux/config/Config.in.ethernet33
-rw-r--r--target/linux/config/Config.in.serial4
-rw-r--r--target/linux/config/Config.in.spi21
-rw-r--r--target/mips/kernel/mikrotik-rb4xx49
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0001-mtd-add-rb4xx-nand-driver.patch351
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0002-phy-add-ethtool-ioctl-support-used-by-ag71xx-driver.patch80
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0003-net-add-ag71xx-mac-driver.patch4185
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0005-spi-add-various-flags-to-spi_transfer-and-spi_messag.patch34
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0006-spi-add-rb4xx-SPI-driver.patch538
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0007-spi-add-rb4xx-cpld-driver.patch525
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0008-gpio-add-GPIO-latch-driver.patch290
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0009-spi-export-spi_bitbang_bufs-function.patch45
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0010-spi-add-type-field-to-spi_transfer-struct.patch37
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0012-mips-ath79-swizzle-PCI-address-for-ar71xx.patch130
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0013-net-add-swconfig-support.patch1837
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0015-phy-add-ar8216-PHY-support.patch4513
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0016-phy-mdio-bitbang-ignore-TA-value.patch44
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0017-MIPS-ath79-fix-maximum-timeout.patch37
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0018-net-allow-PHY-drivers-to-insert-packet-mangle-hooks.patch167
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0019-MIPS-ath79-process-board-cmdline-option.patch26
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0020-spi-ath79-add-fast-flash-read-support.patch202
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0021-phy-add-mdio-boardinfo.patch199
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0022-mips-ath79-add-ath79-ethernet-driver.patch1429
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0023-MIPS-ath79-add-Mikrotik-rb4xx-device-support.patch536
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0024-various-fixups-for-Werror.patch66
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0025-rb4xx_nand-add-partition-for-cfgfs.patch28
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0027-ar71xx-add-zboot-support.patch64
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0028-ag71xx-workaround-some-link-state-bug.patch39
-rw-r--r--target/mips/mikrotik-rb4xx/patches/4.1.6/0029-gpio-add-gpio-latch-driver.patch1261
-rw-r--r--target/mips/systems/mikrotik-rb4xx2
31 files changed, 16715 insertions, 58 deletions
diff --git a/target/config/Config.in.endian.choice b/target/config/Config.in.endian.choice
index cfcf209d4..2bb48a165 100644
--- a/target/config/Config.in.endian.choice
+++ b/target/config/Config.in.endian.choice
@@ -18,6 +18,7 @@ config ADK_TARGET_LITTLE_ENDIAN
bool "Little endian"
depends on !ADK_TARGET_SYSTEM_DRAGINO_MS14S
depends on !ADK_TARGET_SYSTEM_LINKSYS_NSLU2
+ depends on !ADK_TARGET_SYSTEM_MIKROTIK_RB4XX
config ADK_TARGET_BIG_ENDIAN
bool "Big endian"
diff --git a/target/linux/config/Config.in.ethernet b/target/linux/config/Config.in.ethernet
index 7d54775a5..d36a696a2 100644
--- a/target/linux/config/Config.in.ethernet
+++ b/target/linux/config/Config.in.ethernet
@@ -8,6 +8,9 @@ config ADK_KERNEL_NET_CADENCE
config ADK_KERNEL_NET_VENDOR_AMD
bool
+config ADK_KERNEL_NET_VENDOR_ATHEROS
+ bool
+
config ADK_KERNEL_NET_VENDOR_IBM
bool
@@ -47,9 +50,15 @@ config ADK_KERNEL_NET_VENDOR_XILINX
config ADK_KERNEL_PHYLIB
bool
+config ADK_KERNEL_GENERIC_PHY
+ bool
+
config ADK_KERNEL_MII
bool
+config ADK_KERNEL_MDIO_BITBANG
+ bool
+
config ADK_KERNEL_ETRAX_HAVE_PHY
bool
@@ -69,6 +78,30 @@ config ADK_KERNEL_AT803X_PHY
tristate
select ADK_KERNEL_PHYLIB
+config ADK_KERNEL_SWCONFIG
+ bool
+
+config ADK_KERNEL_AG71XX_AR8216_SUPPORT
+ bool
+
+config ADK_KERNEL_AR8216_PHY
+ bool
+
+config ADK_KERNEL_AG71XX
+ tristate "AG71XX ethernet driver"
+ select ADK_KERNEL_NET_VENDOR_ATHEROS
+ select ADK_KERNEL_SWCONFIG
+ select ADK_KERNEL_PHYLIB
+ select ADK_KERNEL_GENERIC_PHY
+ select ADK_KERNEL_MDIO_BITBANG
+ select ADK_KERNEL_AR8216_PHY
+ select ADK_KERNEL_AG71XX_AR8216_SUPPORT
+ depends on ADK_TARGET_SYSTEM_MIKROTIK_RB4XX
+ default y if ADK_TARGET_SYSTEM_MIKROTIK_RB4XX
+ default n
+ help
+ Atheros AG71XX ethernet driver
+
config ADK_KERNEL_FEC
tristate "FEC ethernet driver"
select ADK_KERNEL_NET_VENDOR_FREESCALE
diff --git a/target/linux/config/Config.in.serial b/target/linux/config/Config.in.serial
index c3c6c21ce..d7090cbf4 100644
--- a/target/linux/config/Config.in.serial
+++ b/target/linux/config/Config.in.serial
@@ -43,7 +43,8 @@ config ADK_KERNEL_SERIAL_8250
|| ADK_TARGET_SYSTEM_QEMU_OR1K \
|| ADK_TARGET_SYSTEM_QEMU_PPC_BAMBOO \
|| ADK_TARGET_SYSTEM_IBM_X40 \
- || ADK_TARGET_SYSTEM_MIKROTIK_RB532
+ || ADK_TARGET_SYSTEM_MIKROTIK_RB532 \
+ || ADK_TARGET_SYSTEM_MIKROTIK_RB4XX
default y if ADK_TARGET_SYSTEM_XILINX_KINTEX7
default y if ADK_TARGET_SYSTEM_PCENGINES_APU
default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX
@@ -51,6 +52,7 @@ config ADK_KERNEL_SERIAL_8250
default y if ADK_TARGET_SYSTEM_QEMU_PPC_BAMBOO
default y if ADK_TARGET_SYSTEM_IBM_X40
default y if ADK_TARGET_SYSTEM_MIKROTIK_RB532
+ default y if ADK_TARGET_SYSTEM_MIKROTIK_RB4XX
default n
help
Serial driver for 8250 UART chip.
diff --git a/target/linux/config/Config.in.spi b/target/linux/config/Config.in.spi
index e8a6b45bc..42bbd4b54 100644
--- a/target/linux/config/Config.in.spi
+++ b/target/linux/config/Config.in.spi
@@ -13,17 +13,11 @@ config ADK_KERNEL_SPI_MASTER
config ADK_KERNEL_SPI_BITBANG
tristate
-config ADK_KERNEL_SPI_AR71XX
- tristate
- select ADK_KERNEL_SPI
-
-config ADK_KERNEL_SPI_RB4XX
+config ADK_KERNEL_SPI_RB4XX_CPLD
tristate
- select ADK_KERNEL_SPI
-config ADK_KERNEL_SPI_RB4XX_CPLD
+config ADK_KERNEL_SPI_AR71XX
tristate
- select ADK_KERNEL_SPI
config ADK_KERNEL_SPI_PXA2XX
tristate
@@ -51,6 +45,17 @@ config ADK_KERNEL_SPI_IMX
default y if ADK_TARGET_SYSTEM_SOLIDRUN_IMX6
default n
+config ADK_KERNEL_SPI_RB4XX
+ tristate "SPI driver for Routerboard 4xx"
+ select ADK_KERNEL_SPI
+ select ADK_KERNEL_SPI_MASTER
+ select ADK_KERNEL_SPI_BITBANG
+ select ADK_KERNEL_SPI_RB4XX_CPLD
+ select ADK_KERNEL_SPI_AR71XX
+ depends on ADK_TARGET_SYSTEM_MIKROTIK_RB4XX
+ default y if ADK_TARGET_SYSTEM_MIKROTIK_RB4XX
+ default n
+
config ADK_KERNEL_SPI_SPIDEV
tristate "SPI userland driver"
select ADK_KERNEL_SPI
diff --git a/target/mips/kernel/mikrotik-rb4xx b/target/mips/kernel/mikrotik-rb4xx
index ef3e9fdc3..d8a29ce89 100644
--- a/target/mips/kernel/mikrotik-rb4xx
+++ b/target/mips/kernel/mikrotik-rb4xx
@@ -1,53 +1,6 @@
CONFIG_MIPS=y
CONFIG_ATH79=y
CONFIG_ATH79_MACH_RB4XX=y
-CONFIG_32BIT=y
-CONFIG_PAGE_SIZE_4KB=y
-CONFIG_HZ=100
CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_MTD_M25P80=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_RB4XX=y
-CONFIG_NET_VENDOR_ATHEROS=y
-CONFIG_AG71XX=y
-CONFIG_AG71XX_AR8216_SUPPORT=y
-CONFIG_PHYLIB=y
-CONFIG_MDIO_BOARDINFO=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_LEDS=y
-CONFIG_AR8216_PHY=y
-CONFIG_AR8216_PHY_LEDS=y
-CONFIG_MDIO_BITBANG=y
+CONFIG_CMDLINE_BOOL=y
CONFIG_MDIO_GPIO=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_RUNTIME_UARTS=1
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_GPIO=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_ATH79=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_RB4XX=y
-CONFIG_SPI_RB4XX_CPLD=y
-CONFIG_GPIO_LATCH=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_ATH79_WDT=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_SPI=y
-CONFIG_LEDS_GPIO=y
-CONFIG_WATCHDOG=y
-CONFIG_ATH79_WDT=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_GENERIC_PHY=y
diff --git a/target/mips/mikrotik-rb4xx/patches/4.1.6/0001-mtd-add-rb4xx-nand-driver.patch b/target/mips/mikrotik-rb4xx/patches/4.1.6/0001-mtd-add-rb4xx-nand-driver.patch
new file mode 100644
index 000000000..8199de991
--- /dev/null
+++ b/target/mips/mikrotik-rb4xx/patches/4.1.6/0001-mtd-add-rb4xx-nand-driver.patch
@@ -0,0 +1,351 @@
+From 1e692cc0c53202b932eedabd0315107910c5b093 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <phil@nwl.cc>
+Date: Tue, 13 May 2014 00:08:54 +0200
+Subject: [PATCH] mtd: add rb4xx nand driver
+
+---
+ drivers/mtd/nand/Kconfig | 4 +
+ drivers/mtd/nand/Makefile | 1 +
+ drivers/mtd/nand/rb4xx_nand.c | 305 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 310 insertions(+)
+ create mode 100644 drivers/mtd/nand/rb4xx_nand.c
+
+diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
+index 90ff447..bb01309 100644
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -510,4 +510,8 @@ config MTD_NAND_XWAY
+ Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
+ to the External Bus Unit (EBU).
+
++config MTD_NAND_RB4XX
++ tristate "NAND flash driver for RouterBoard 4xx series"
++ depends on MTD_NAND && ATH79_MACH_RB4XX
++
+ endif # MTD_NAND
+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
+index 542b568..e2b5e1c 100644
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -31,6 +31,7 @@ obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
+ obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
+ obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
+ obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
++obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
+ obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
+ obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
+ obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o
+diff --git a/drivers/mtd/nand/rb4xx_nand.c b/drivers/mtd/nand/rb4xx_nand.c
+new file mode 100644
+index 0000000..5b9841b
+--- /dev/null
++++ b/drivers/mtd/nand/rb4xx_nand.c
+@@ -0,0 +1,305 @@
++/*
++ * NAND flash driver for the MikroTik RouterBoard 4xx series
++ *
++ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ *
++ * This file was based on the driver for Linux 2.6.22 published by
++ * MikroTik for their RouterBoard 4xx series devices.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/gpio.h>
++#include <linux/slab.h>
++
++#include <asm/mach-ath79/ath79.h>
++#include <asm/mach-ath79/rb4xx_cpld.h>
++
++#define DRV_NAME "rb4xx-nand"
++#define DRV_VERSION "0.2.0"
++#define DRV_DESC "NAND flash driver for RouterBoard 4xx series"
++
++#define RB4XX_NAND_GPIO_READY 5
++#define RB4XX_NAND_GPIO_ALE 37
++#define RB4XX_NAND_GPIO_CLE 38
++#define RB4XX_NAND_GPIO_NCE 39
++
++struct rb4xx_nand_info {
++ struct nand_chip chip;
++ struct mtd_info mtd;
++};
++
++/*
++ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
++ * will not be able to find the kernel that we load.
++ */
++static struct nand_ecclayout rb4xx_nand_ecclayout = {
++ .eccbytes = 6,
++ .eccpos = { 8, 9, 10, 13, 14, 15 },
++ .oobavail = 9,
++ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
++};
++
++static struct mtd_partition rb4xx_nand_partitions[] = {
++ {
++ .name = "booter",
++ .offset = 0,
++ .size = (256 * 1024),
++ .mask_flags = MTD_WRITEABLE,
++ },
++ {
++ .name = "kernel",
++ .offset = (256 * 1024),
++ .size = (4 * 1024 * 1024) - (256 * 1024),
++ },
++ {
++ .name = "rootfs",
++ .offset = MTDPART_OFS_NXTBLK,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static int rb4xx_nand_dev_ready(struct mtd_info *mtd)
++{
++ return gpio_get_value_cansleep(RB4XX_NAND_GPIO_READY);
++}
++
++static void rb4xx_nand_write_cmd(unsigned char cmd)
++{
++ unsigned char data = cmd;
++ int err;
++
++ err = rb4xx_cpld_write(&data, 1);
++ if (err)
++ pr_err("rb4xx_nand: write cmd failed, err=%d\n", err);
++}
++
++static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
++ unsigned int ctrl)
++{
++ if (ctrl & NAND_CTRL_CHANGE) {
++ gpio_set_value_cansleep(RB4XX_NAND_GPIO_CLE,
++ (ctrl & NAND_CLE) ? 1 : 0);
++ gpio_set_value_cansleep(RB4XX_NAND_GPIO_ALE,
++ (ctrl & NAND_ALE) ? 1 : 0);
++ gpio_set_value_cansleep(RB4XX_NAND_GPIO_NCE,
++ (ctrl & NAND_NCE) ? 0 : 1);
++ }
++
++ if (cmd != NAND_CMD_NONE)
++ rb4xx_nand_write_cmd(cmd);
++}
++
++static unsigned char rb4xx_nand_read_byte(struct mtd_info *mtd)
++{
++ unsigned char data = 0;
++ int err;
++
++ err = rb4xx_cpld_read(&data, NULL, 1);
++ if (err) {
++ pr_err("rb4xx_nand: read data failed, err=%d\n", err);
++ data = 0xff;
++ }
++
++ return data;
++}
++
++static void rb4xx_nand_write_buf(struct mtd_info *mtd, const unsigned char *buf,
++ int len)
++{
++ int err;
++
++ err = rb4xx_cpld_write(buf, len);
++ if (err)
++ pr_err("rb4xx_nand: write buf failed, err=%d\n", err);
++}
++
++static void rb4xx_nand_read_buf(struct mtd_info *mtd, unsigned char *buf,
++ int len)
++{
++ int err;
++
++ err = rb4xx_cpld_read(buf, NULL, len);
++ if (err)
++ pr_err("rb4xx_nand: read buf failed, err=%d\n", err);
++}
++
++static int rb4xx_nand_probe(struct platform_device *pdev)
++{
++ struct rb4xx_nand_info *info;
++ int ret;
++
++ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
++
++ ret = gpio_request(RB4XX_NAND_GPIO_READY, "NAND RDY");
++ if (ret) {
++ dev_err(&pdev->dev, "unable to request gpio %d\n",
++ RB4XX_NAND_GPIO_READY);
++ goto err;
++ }
++
++ ret = gpio_direction_input(RB4XX_NAND_GPIO_READY);
++ if (ret) {
++ dev_err(&pdev->dev, "unable to set input mode on gpio %d\n",
++ RB4XX_NAND_GPIO_READY);
++ goto err_free_gpio_ready;
++ }
++
++ ret = gpio_request(RB4XX_NAND_GPIO_ALE, "NAND ALE");
++ if (ret) {
++ dev_err(&pdev->dev, "unable to request gpio %d\n",
++ RB4XX_NAND_GPIO_ALE);
++ goto err_free_gpio_ready;
++ }
++
++ ret = gpio_direction_output(RB4XX_NAND_GPIO_ALE, 0);
++ if (ret) {
++ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n",
++ RB4XX_NAND_GPIO_ALE);
++ goto err_free_gpio_ale;
++ }
++
++ ret = gpio_request(RB4XX_NAND_GPIO_CLE, "NAND CLE");
++ if (ret) {
++ dev_err(&pdev->dev, "unable to request gpio %d\n",
++ RB4XX_NAND_GPIO_CLE);
++ goto err_free_gpio_ale;
++ }
++
++ ret = gpio_direction_output(RB4XX_NAND_GPIO_CLE, 0);
++ if (ret) {
++ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n",
++ RB4XX_NAND_GPIO_CLE);
++ goto err_free_gpio_cle;
++ }
++
++ ret = gpio_request(RB4XX_NAND_GPIO_NCE, "NAND NCE");
++ if (ret) {
++ dev_err(&pdev->dev, "unable to request gpio %d\n",
++ RB4XX_NAND_GPIO_NCE);
++ goto err_free_gpio_cle;
++ }
++
++ ret = gpio_direction_output(RB4XX_NAND_GPIO_NCE, 1);
++ if (ret) {
++ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n",
++ RB4XX_NAND_GPIO_ALE);
++ goto err_free_gpio_nce;
++ }
++
++ info = kzalloc(sizeof(*info), GFP_KERNEL);
++ if (!info) {
++ dev_err(&pdev->dev, "rb4xx-nand: no memory for private data\n");
++ ret = -ENOMEM;
++ goto err_free_gpio_nce;
++ }
++
++ info->chip.priv = &info;
++ info->mtd.priv = &info->chip;
++ info->mtd.owner = THIS_MODULE;
++
++ info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl;
++ info->chip.dev_ready = rb4xx_nand_dev_ready;
++ info->chip.read_byte = rb4xx_nand_read_byte;
++ info->chip.write_buf = rb4xx_nand_write_buf;
++ info->chip.read_buf = rb4xx_nand_read_buf;
++
++ info->chip.chip_delay = 25;
++ info->chip.ecc.mode = NAND_ECC_SOFT;
++
++ platform_set_drvdata(pdev, info);
++
++ ret = nand_scan_ident(&info->mtd, 1, NULL);
++ if (ret) {
++ ret = -ENXIO;
++ goto err_free_info;
++ }
++
++ if (info->mtd.writesize == 512)
++ info->chip.ecc.layout = &rb4xx_nand_ecclayout;
++
++ ret = nand_scan_tail(&info->mtd);
++ if (ret) {
++ return -ENXIO;
++ goto err_set_drvdata;
++ }
++
++ mtd_device_register(&info->mtd, rb4xx_nand_partitions,
++ ARRAY_SIZE(rb4xx_nand_partitions));
++ if (ret)
++ goto err_release_nand;
++
++ return 0;
++
++err_release_nand:
++ nand_release(&info->mtd);
++err_set_drvdata:
++ platform_set_drvdata(pdev, NULL);
++err_free_info:
++ kfree(info);
++err_free_gpio_nce:
++ gpio_free(RB4XX_NAND_GPIO_NCE);
++err_free_gpio_cle:
++ gpio_free(RB4XX_NAND_GPIO_CLE);
++err_free_gpio_ale:
++ gpio_free(RB4XX_NAND_GPIO_ALE);
++err_free_gpio_ready:
++ gpio_free(RB4XX_NAND_GPIO_READY);
++err:
++ return ret;
++}
++
++static int rb4xx_nand_remove(struct platform_device *pdev)
++{
++ struct rb4xx_nand_info *info = platform_get_drvdata(pdev);
++
++ nand_release(&info->mtd);
++ platform_set_drvdata(pdev, NULL);
++ kfree(info);
++ gpio_free(RB4XX_NAND_GPIO_NCE);
++ gpio_free(RB4XX_NAND_GPIO_CLE);
++ gpio_free(RB4XX_NAND_GPIO_ALE);
++ gpio_free(RB4XX_NAND_GPIO_READY);
++
++ return 0;
++}
++
++static struct platform_driver rb4xx_nand_driver = {
++ .probe = rb4xx_nand_probe,
++ .remove = rb4xx_nand_remove,
++ .driver = {
++ .name = DRV_NAME,
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init rb4xx_nand_init(void)
++{
++ return platform_driver_register(&rb4xx_nand_driver);
++}
++
++static void __exit rb4xx_nand_exit(void)
++{
++ platform_driver_unregister(&rb4xx_nand_driver);
++}
++
++module_init(rb4xx_nand_init);
++module_exit(rb4xx_nand_exit);
++
++MODULE_DESCRIPTION(DRV_DESC);
++MODULE_VERSION(DRV_VERSION);
++MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
++MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
++MODULE_LICENSE("GPL v2");
+--
+1.8.5.3
+
diff --git a/target/mips/mikrotik-rb4xx/patches/4.1.6/0002-phy-add-ethtool-ioctl-support-used-by-ag71xx-driver.patch b/target/mips/mikrotik-rb4xx/patches/4.1.6/0002-phy-add-ethtool-ioctl-support-used-by-ag71xx-driver.patch
new file mode 100644
index 000000000..ba7fbfad8
--- /dev/null
+++ b/target/mips/mikrotik-rb4xx/patches/4.1.6/0002-phy-add-ethtool-ioctl-support-used-by-ag71xx-driver.patch
@@ -0,0 +1,80 @@
+From 7b864612a6e3b139a5a607abd0048a19078fe42f Mon Sep 17 00:00:00 2001
+From: Phil Sutter <phil@nwl.cc>
+Date: Wed, 14 May 2014 02:55:06 +0200
+Subject: [PATCH] phy: add ethtool ioctl support, used by ag71xx driver
+
+---
+ drivers/net/phy/phy.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/phy.h | 1 +
+ 2 files changed, 45 insertions(+)
+
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index 76d96b9..9439ef3 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -293,6 +293,50 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
+ }
+ EXPORT_SYMBOL(phy_ethtool_gset);
+
++int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
++{
++ u32 cmd;
++ int tmp;
++ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
++ struct ethtool_value edata = { ETHTOOL_GLINK };
++
++ if (get_user(cmd, (u32 *) useraddr))
++ return -EFAULT;
++
++ switch (cmd) {
++ case ETHTOOL_GSET:
++ phy_ethtool_gset(phydev, &ecmd);
++ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
++ return -EFAULT;
++ return 0;
++
++ case ETHTOOL_SSET:
++ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
++ return -EFAULT;
++ return phy_ethtool_sset(phydev, &ecmd);
++
++ case ETHTOOL_NWAY_RST:
++ /* if autoneg is off, it's an error */
++ tmp = phy_read(phydev, MII_BMCR);
++ if (tmp & BMCR_ANENABLE) {
++ tmp |= (BMCR_ANRESTART);
++ phy_write(phydev, MII_BMCR, tmp);
++ return 0;
++ }
++ return -EINVAL;
++
++ case ETHTOOL_GLINK:
++ edata.data = (phy_read(phydev,
++ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
++ if (copy_to_user(useraddr, &edata, sizeof(edata)))
++ return -EFAULT;
++ return 0;
++ }
++
++ return -EOPNOTSUPP;
++}
++EXPORT_SYMBOL(phy_ethtool_ioctl);
++
+ /**
+ * phy_mii_ioctl - generic PHY MII ioctl interface
+ * @phydev: the phy_device struct
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index 565188c..9ab0d79 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -628,6 +628,7 @@ void phy_stop_machine(struct phy_device *phydev);
+ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
+ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
+ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
++int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
+ int phy_start_interrupts(struct phy_device *phydev);
+ void phy_print_status(struct phy_device *phydev);
+ void phy_device_free(struct phy_device *phydev);
+--
+1.8.5.3
+
diff --git a/target/mips/mikrotik-rb4xx/patches/4.1.6/0003-net-add-ag71xx-mac-driver.patch b/target/mips/mikrotik-rb4xx/patches/4.1.6/0003-net-add-ag71xx-mac-driver.patch
new file mode 100644
index 000000000..f8db1f2a4
--- /dev/null
+++ b/target/mips/mikrotik-rb4xx/patches/4.1.6/0003-net-add-ag71xx-mac-driver.patch
@@ -0,0 +1,4185 @@
+diff -Nur linux-4.1.6.orig/arch/mips/include/asm/mach-ath79/ag71xx_platform.h linux-4.1.6/arch/mips/include/asm/mach-ath79/ag71xx_platform.h
+--- linux-4.1.6.orig/arch/mips/include/asm/mach-ath79/ag71xx_platform.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-4.1.6/arch/mips/include/asm/mach-ath79/ag71xx_platform.h 2015-09-13 19:45:36.374555224 +0200
+@@ -0,0 +1,65 @@
++/*
++ * Atheros AR71xx SoC specific platform data definitions
++ *
++ * Copyright (C) 2008-2012 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#ifndef __ASM_MACH_ATH79_PLATFORM_H
++#define __ASM_MACH_ATH79_PLATFORM_H
++
++#include <linux/if_ether.h>
++#include <linux/skbuff.h>
++#include <linux/phy.h>
++#include <linux/spi/spi.h>
++
++struct ag71xx_switch_platform_data {
++ u8 phy4_mii_en:1;
++ u8 phy_poll_mask;
++};
++
++struct ag71xx_platform_data {
++ phy_interface_t phy_if_mode;
++ u32 phy_mask;
++ int speed;
++ int duplex;
++ u32 reset_bit;
++ u8 mac_addr[ETH_ALEN];
++ struct device *mii_bus_dev;
++
++ u8 has_gbit:1;
++ u8 is_ar91xx:1;
++ u8 is_ar7240:1;
++ u8 is_ar724x:1;
++ u8 has_ar8216:1;
++
++ struct ag71xx_switch_platform_data *switch_data;
++
++ void (*ddr_flush)(void);
++ void (*set_speed)(int speed);
++
++ u32 fifo_cfg1;
++ u32 fifo_cfg2;
++ u32 fifo_cfg3;
++
++ unsigned int max_frame_len;
++ unsigned int desc_pktlen_mask;
++};
++
++struct ag71xx_mdio_platform_data {
++ u32 phy_mask;
++ u8 builtin_switch:1;
++ u8 is_ar7240:1;
++ u8 is_ar9330:1;
++ u8 is_ar934x:1;
++ unsigned long mdio_clock;
++ unsigned long ref_clock;
++
++ void (*reset)(struct mii_bus *bus);
++};
++
++#endif /* __ASM_MACH_ATH79_PLATFORM_H */
+diff -Nur linux-4.1.6.orig/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c linux-4.1.6/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
+--- linux-4.1.6.orig/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-4.1.6/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c 2015-09-13 19:45:36.374555224 +0200
+@@ -0,0 +1,1202 @@
++/*
++ * Driver for the built-in ethernet switch of the Atheros AR7240 SoC
++ * Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (c) 2010 Felix Fietkau <nbd@openwrt.org>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ */
++
++#include <linux/etherdevice.h>
++#include <linux/list.h>
++#include <linux/netdevice.h>
++#include <linux/phy.h>
++#include <linux/mii.h>
++#include <linux/bitops.h>
++#include <linux/switch.h>
++#include "ag71xx.h"
++
++#define BITM(_count) (BIT(_count) - 1)
++#define BITS(_shift, _count) (BITM(_count) << _shift)
++
++#define AR7240_REG_MASK_CTRL 0x00
++#define AR7240_MASK_CTRL_REVISION_M BITM(8)
++#define AR7240_MASK_CTRL_VERSION_M BITM(8)
++#define AR7240_MASK_CTRL_VERSION_S 8
++#define AR7240_MASK_CTRL_VERSION_AR7240 0x01
++#define AR7240_MASK_CTRL_VERSION_AR934X 0x02
++#define AR7240_MASK_CTRL_SOFT_RESET BIT(31)
++
++#define AR7240_REG_MAC_ADDR0 0x20
++#define AR7240_REG_MAC_ADDR1 0x24
++
++#define AR7240_REG_FLOOD_MASK 0x2c
++#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26)
++
++#define AR7240_REG_GLOBAL_CTRL 0x30
++#define AR7240_GLOBAL_CTRL_MTU_M BITM(11)
++#define AR9340_GLOBAL_CTRL_MTU_M BITM(14)
++
++#define AR7240_REG_VTU 0x0040
++#define AR7240_VTU_OP BITM(3)
++#define AR7240_VTU_OP_NOOP 0x0
++#define AR7240_VTU_OP_FLUSH 0x1
++#define AR7240_VTU_OP_LOAD 0x2
++#define AR7240_VTU_OP_PURGE 0x3
++#define AR7240_VTU_OP_REMOVE_PORT 0x4
++#define AR7240_VTU_ACTIVE BIT(3)
++#define AR7240_VTU_FULL BIT(4)
++#define AR7240_VTU_PORT BITS(8, 4)
++#define AR7240_VTU_PORT_S 8
++#define AR7240_VTU_VID BITS(16, 12)
++#define AR7240_VTU_VID_S 16
++#define AR7240_VTU_PRIO BITS(28, 3)
++#define AR7240_VTU_PRIO_S 28
++#define AR7240_VTU_PRIO_EN BIT(31)
++
++#define AR7240_REG_VTU_DATA 0x0044
++#define AR7240_VTUDATA_MEMBER BITS(0, 10)
++#define AR7240_VTUDATA_VALID BIT(11)
++
++#define AR7240_REG_ATU 0x50
++#define AR7240_ATU_FLUSH_ALL 0x1
++
++#define AR7240_REG_AT_CTRL 0x5c
++#define AR7240_AT_CTRL_AGE_TIME BITS(0, 15)
++#define AR7240_AT_CTRL_AGE_EN BIT(17)
++#define AR7240_AT_CTRL_LEARN_CHANGE BIT(18)
++#define AR7240_AT_CTRL_RESERVED BIT(19)
++#define AR7240_AT_CTRL_ARP_EN BIT(20)
++
++#define AR7240_REG_TAG_PRIORITY 0x70
++
++#define AR7240_REG_SERVICE_TAG 0x74
++#define AR7240_SERVICE_TAG_M BITM(16)
++
++#define AR7240_REG_CPU_PORT 0x78
++#define AR7240_MIRROR_PORT_S 4
++#define AR7240_CPU_PORT_EN BIT(8)
++
++#define AR7240_REG_MIB_FUNCTION0 0x80
++#define AR7240_MIB_TIMER_M BITM(16)
++#define AR7240_MIB_AT_HALF_EN BIT(16)
++#define AR7240_MIB_BUSY BIT(17)
++#define AR7240_MIB_FUNC_S 24
++#define AR7240_MIB_FUNC_M BITM(3)
++#define AR7240_MIB_FUNC_NO_OP 0x0
++#define AR7240_MIB_FUNC_FLUSH 0x1
++#define AR7240_MIB_FUNC_CAPTURE 0x3
++
++#define AR7240_REG_MDIO_CTRL 0x98
++#define AR7240_MDIO_CTRL_DATA_M BITM(16)
++#define AR7240_MDIO_CTRL_REG_ADDR_S 16
++#define AR7240_MDIO_CTRL_PHY_ADDR_S 21
++#define AR7240_MDIO_CTRL_CMD_WRITE 0
++#define AR7240_MDIO_CTRL_CMD_READ BIT(27)
++#define AR7240_MDIO_CTRL_MASTER_EN BIT(30)
++#define AR7240_MDIO_CTRL_BUSY BIT(31)
++
++#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100)
++
++#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00)
<