diff --git a/scripts/arm-magic.sh b/scripts/arm-magic.sh
index e40f9fb17f38505c0165b0eb397ecb0cd71cb540..eff9b4d414583fc09a1bbce41f920b8db2ac7af7 100755
--- a/scripts/arm-magic.sh
+++ b/scripts/arm-magic.sh
@@ -22,7 +22,7 @@
 # NOTE: for now it's for only IXP4xx in big endian mode
 
 # list of supported boards, in "boardname machtypeid" format
-for board in "avila 526" "gateway7001 731" "nslu2 597" "nas100d 865" "wg302v1 889" "wg302v2 890" "pronghorn 928" "pronghornmetro 1040" "compex 1273" "wrt300nv2 1077" "loft 849" "dsmg600 964" "fsg3 1091" "ap1000 1543" "tw2662 1658" "tw5334 1664" "ixdpg425 604" "cambria 1468" "sidewinder 1041"
+for board in "avila 526" "gateway7001 731" "nslu2 597" "nas100d 865" "wg302v1 889" "wg302v2 890" "pronghorn 928" "pronghornmetro 1040" "compex 1273" "wrt300nv2 1077" "loft 849" "dsmg600 964" "fsg3 1091" "ap1000 1543" "tw2662 1658" "tw5334 1664" "ixdpg425 604" "cambria 1468" "sidewinder 1041" "ap42x 4418"
 do
   set -- $board
   hexid=$(printf %x\\n $2)
diff --git a/target/linux/generic/patches-3.3/980-arm_openwrt_machtypes.patch b/target/linux/generic/patches-3.3/980-arm_openwrt_machtypes.patch
index 44383188dfa845ebb7c500416c3645ab52b2268d..8204318986c1d874a46fa20a556eecd3fd31ce3d 100644
--- a/target/linux/generic/patches-3.3/980-arm_openwrt_machtypes.patch
+++ b/target/linux/generic/patches-3.3/980-arm_openwrt_machtypes.patch
@@ -1,6 +1,6 @@
 --- a/arch/arm/tools/mach-types
 +++ b/arch/arm/tools/mach-types
-@@ -1169,3 +1169,30 @@ elite_ulk		MACH_ELITE_ULK		ELITE_ULK		38
+@@ -1169,3 +1169,31 @@ elite_ulk		MACH_ELITE_ULK		ELITE_ULK		38
  pov2			MACH_POV2		POV2			3889
  ipod_touch_2g		MACH_IPOD_TOUCH_2G	IPOD_TOUCH_2G		3890
  da850_pqab		MACH_DA850_PQAB		DA850_PQAB		3891
@@ -31,3 +31,4 @@
 +wn802t			MACH_WN802T		WN802T			3306
 +nsa310			MACH_NSA310		NSA310			4022
 +wnr3500			MACH_WNR3500		WNR3500			4407
++ap42x			MACH_AP42X		AP42X			4418
diff --git a/target/linux/generic/patches-3.6/980-arm_openwrt_machtypes.patch b/target/linux/generic/patches-3.6/980-arm_openwrt_machtypes.patch
index cca77af5164e8d6649ccbf4402a2619b4db9294a..954f658699991b534c2f680fe5d5b91476e2fb60 100644
--- a/target/linux/generic/patches-3.6/980-arm_openwrt_machtypes.patch
+++ b/target/linux/generic/patches-3.6/980-arm_openwrt_machtypes.patch
@@ -1,6 +1,6 @@
 --- a/arch/arm/tools/mach-types
 +++ b/arch/arm/tools/mach-types
-@@ -1206,3 +1206,30 @@ baileys			MACH_BAILEYS		BAILEYS			4169
+@@ -1206,3 +1206,31 @@ baileys			MACH_BAILEYS		BAILEYS			4169
  familybox		MACH_FAMILYBOX		FAMILYBOX		4170
  ensemble_mx35		MACH_ENSEMBLE_MX35	ENSEMBLE_MX35		4171
  sc_sps_1		MACH_SC_SPS_1		SC_SPS_1		4172
@@ -31,3 +31,4 @@
 +wn802t			MACH_WN802T		WN802T			3306
 +nsa310			MACH_NSA310		NSA310			4022
 +wnr3500			MACH_WNR3500		WNR3500			4407
++ap42x			MACH_AP42X		AP42X			4418
diff --git a/target/linux/ixp4xx/base-files/lib/preinit/05_set_ether_mac_ixp4xx b/target/linux/ixp4xx/base-files/lib/preinit/05_set_ether_mac_ixp4xx
index e19e0ec2509ddb433b22b0559d626a4e48b975bd..e707dabf056f4e47629fdc69d88713c28f6f1360 100644
--- a/target/linux/ixp4xx/base-files/lib/preinit/05_set_ether_mac_ixp4xx
+++ b/target/linux/ixp4xx/base-files/lib/preinit/05_set_ether_mac_ixp4xx
@@ -17,6 +17,15 @@ set_ether_mac() {
 	if [ "$(ifconfig eth0 2>/dev/null | grep -c 00:00:00:00:00:00)" == "1" ]; then
 			ifconfig eth0 hw ether $(fconfig -s -r -d /dev/$RB_CONFIG -n zcom_npe_esa)
 	fi
+
+	# Others (*cough*, Tonze) are dumb enough to not handle mac addresses at all
+
+	if [ "$(ifconfig eth0 2>/dev/null | grep -c 00:00:00:00:00:00)" == "1" ]; then
+		ifconfig eth0 hw ether 00:11:22:33:44:55
+	fi
+	if [ "$(ifconfig eth1 2>/dev/null | grep -c 00:00:00:00:00:00)" == "1" ]; then
+		ifconfig eth1 hw ether 00:11:22:33:44:56
+	fi
 }
 
 boot_hook_add preinit_main set_ether_mac
diff --git a/target/linux/ixp4xx/config-3.3 b/target/linux/ixp4xx/config-3.3
index f7a1694156f915b9c50655b27586a981321f3de1..60039e14cbc8fdd5730cde8ceeb9e84c306c04f1 100644
--- a/target/linux/ixp4xx/config-3.3
+++ b/target/linux/ixp4xx/config-3.3
@@ -117,6 +117,7 @@ CONFIG_LEDS_LATCH=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_MACH_AP1000=y
+CONFIG_MACH_AP42X=y
 # CONFIG_MACH_ARCOM_VULCAN is not set
 CONFIG_MACH_AVILA=y
 CONFIG_MACH_CAMBRIA=y
@@ -151,6 +152,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
 # CONFIG_MTD_CFI_GEOMETRY is not set
 CONFIG_MTD_IXP4XX=y
 CONFIG_MTD_OTP=y
+CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_NEED_PER_CPU_KM=y
diff --git a/target/linux/ixp4xx/patches-3.3/530-ap42x_support.patch b/target/linux/ixp4xx/patches-3.3/530-ap42x_support.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c46fdbbd4f148e8084b2d6b6caa7ae632fd129ee
--- /dev/null
+++ b/target/linux/ixp4xx/patches-3.3/530-ap42x_support.patch
@@ -0,0 +1,280 @@
+--- /dev/null
++++ b/arch/arm/mach-ixp4xx/ap42x-pci.c
+@@ -0,0 +1,64 @@
++/*
++ * arch/arch/mach-ixp4xx/ap42x-pci.c
++ *
++ * PCI setup routines for Tonze AP-422/425
++ *
++ * Copyright (C) 2012 Imre Kaloz <kaloz@openwrt.org>
++ *
++ * based on coyote-pci.c:
++ *	Copyright (C) 2002 Jungo Software Technologies.
++ *	Copyright (C) 2003 MontaVista Softwrae, Inc.
++ *
++ * Maintainer: 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.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/irq.h>
++
++#include <asm/mach-types.h>
++#include <mach/hardware.h>
++
++#include <asm/mach/pci.h>
++
++void __init ap42x_pci_preinit(void)
++{
++	irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
++	irq_set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
++
++	ixp4xx_pci_preinit();
++}
++
++static int __init ap42x_map_irq(const struct pci_dev *dev, u8 slot,
++	u8 pin)
++{
++	if (slot == 1)
++		return IRQ_IXP4XX_GPIO11;
++	else if (slot == 2)
++		return IRQ_IXP4XX_GPIO10;
++	else return -1;
++}
++
++struct hw_pci ap42x_pci __initdata = {
++	.nr_controllers = 1,
++	.preinit	= ap42x_pci_preinit,
++	.swizzle	= pci_std_swizzle,
++	.setup		= ixp4xx_setup,
++	.scan		= ixp4xx_scan_bus,
++	.map_irq	= ap42x_map_irq,
++};
++
++int __init ap42x_pci_init(void)
++{
++	if (machine_is_ap42x())
++		pci_common_init(&ap42x_pci);
++	return 0;
++}
++
++subsys_initcall(ap42x_pci_init);
+--- /dev/null
++++ b/arch/arm/mach-ixp4xx/ap42x-setup.c
+@@ -0,0 +1,163 @@
++/*
++ * arch/arm/mach-ixp4xx/ap42x-setup.c
++ *
++ * Board setup for the Tonze AP-42x boards
++ *
++ * Copyright (C) 2012 Imre Kaloz <kaloz@openwrt.org>
++ *
++ * based on coyote-setup.c:
++ *      Copyright (C) 2003-2005 MontaVista Software, Inc.
++ *
++ * Author: Imre Kaloz <Kaloz@openwrt.org>
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/serial.h>
++#include <linux/tty.h>
++#include <linux/serial_8250.h>
++#include <linux/mtd/physmap.h>
++
++#include <asm/types.h>
++#include <asm/setup.h>
++#include <asm/memory.h>
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/flash.h>
++
++static struct mtd_partition ap42x_flash_partitions[] = {
++	{
++		.name		= "RedBoot",
++		.offset		= 0x00000000,
++		.size		= 0x00080000,
++	}, {
++		.name		= "linux",
++		.offset		= 0x00080000,
++		.size		= 0x00100000,
++	}, {
++		.name		= "rootfs",
++		.offset		= 0x00180000,
++		.size		= 0x00660000,
++	}, {
++		.name		= "FIS directory",
++		.offset		= 0x007f8000,
++		.size		= 0x00007000,
++	}, {
++		.name		= "RedBoot config",
++		.offset		= 0x007ff000,
++		.size		= 0x00001000,
++	},
++};
++
++static struct physmap_flash_data ap42x_flash_data = {
++	.width		= 2,
++	.parts		= ap42x_flash_partitions,
++	.nr_parts	= ARRAY_SIZE(ap42x_flash_partitions),
++};
++
++static struct resource ap42x_flash_resource = {
++	.flags		= IORESOURCE_MEM,
++	.start		= IXP4XX_EXP_BUS_BASE_PHYS,
++	.end		= IXP4XX_EXP_BUS_BASE_PHYS + SZ_8M - 1,
++};
++
++static struct platform_device ap42x_flash = {
++	.name			= "physmap-flash",
++	.id			= 0,
++	.dev		= {
++		.platform_data	= &ap42x_flash_data,
++	},
++	.num_resources		= 1,
++	.resource		= &ap42x_flash_resource,
++};
++
++static struct resource ap42x_uart_resource = {
++	.start	= IXP4XX_UART2_BASE_PHYS,
++	.end	= IXP4XX_UART2_BASE_PHYS + 0x0fff,
++	.flags	= IORESOURCE_MEM,
++};
++
++static struct plat_serial8250_port ap42x_uart_data[] = {
++	{
++		.mapbase	= IXP4XX_UART2_BASE_PHYS,
++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
++		.irq		= IRQ_IXP4XX_UART2,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++		.iotype		= UPIO_MEM,
++		.regshift	= 2,
++		.uartclk	= IXP4XX_UART_XTAL,
++	},
++	{ },
++};
++
++static struct platform_device ap42x_uart = {
++	.name		= "serial8250",
++	.id		= PLAT8250_DEV_PLATFORM,
++	.dev			= {
++		.platform_data	= ap42x_uart_data,
++	},
++	.num_resources	= 1,
++	.resource	= &ap42x_uart_resource,
++};
++
++static struct eth_plat_info ap42x_plat_eth[] = {
++	{
++		.phy		= 2,
++		.rxq		= 3,
++		.txreadyq	= 20,
++	}, {
++		.phy		= 1,
++		.rxq		= 4,
++		.txreadyq	= 21,
++	}
++};
++
++static struct platform_device ap42x_eth[] = {
++	{
++		.name			= "ixp4xx_eth",
++		.id			= IXP4XX_ETH_NPEB,
++		.dev.platform_data	= ap42x_plat_eth,
++	}, {
++		.name			= "ixp4xx_eth",
++		.id			= IXP4XX_ETH_NPEC,
++		.dev.platform_data	= ap42x_plat_eth + 1,
++	}
++};
++
++static struct platform_device *ap42x_devices[] __initdata = {
++	&ap42x_flash,
++	&ap42x_uart,
++	&ap42x_eth[0],
++	&ap42x_eth[1],
++};
++
++static void __init ap42x_init(void)
++{
++	ixp4xx_sys_init();
++
++	ap42x_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
++	ap42x_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
++
++	*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
++	*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
++
++	platform_add_devices(ap42x_devices, ARRAY_SIZE(ap42x_devices));
++}
++
++#ifdef CONFIG_MACH_AP42X
++MACHINE_START(AP42X, "Tonze AP-422/425")
++	/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
++	.map_io		= ixp4xx_map_io,
++	.init_irq	= ixp4xx_init_irq,
++	.timer		= &ixp4xx_timer,
++	.atag_offset	= 0x100,
++	.init_machine	= ap42x_init,
++#if defined(CONFIG_PCI)
++	.dma_zone_size	= SZ_64M,
++#endif
++	.restart	= ixp4xx_restart,
++MACHINE_END
++#endif
+--- a/arch/arm/mach-ixp4xx/include/mach/uncompress.h
++++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
+@@ -45,7 +45,8 @@ static __inline__ void __arch_decomp_set
+ 	    machine_is_devixp() || machine_is_miccpt() || machine_is_mic256() ||
+ 	    machine_is_pronghorn() || machine_is_pronghorn_metro() ||
+ 	    machine_is_wrt300nv2() || machine_is_tw5334() ||
+-	    machine_is_usr8200() || machine_is_tw2662())
++	    machine_is_usr8200() || machine_is_tw2662() ||
++	    machine_is_ap42x())
+ 		uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS;
+ 	else
+ 		uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS;
+--- a/arch/arm/mach-ixp4xx/Kconfig
++++ b/arch/arm/mach-ixp4xx/Kconfig
+@@ -8,6 +8,14 @@ menu "Intel IXP4xx Implementation Option
+ 
+ comment "IXP4xx Platforms"
+ 
++config MACH_AP42X
++	bool "Tonze AP-422/425"
++	select PCI
++	help
++	  Say 'Y' here if you want your kernel to support Tonze's
++	  AP-422/425 boards. For more information on this platform,
++	  see http://tonze.com.tw
++
+ config MACH_NSLU2
+ 	bool
+ 	prompt "Linksys NSLU2"
+--- a/arch/arm/mach-ixp4xx/Makefile
++++ b/arch/arm/mach-ixp4xx/Makefile
+@@ -5,6 +5,7 @@
+ obj-pci-y	:=
+ obj-pci-n	:=
+ 
++obj-pci-$(CONFIG_MACH_AP42X)		+= ap42x-pci.o
+ obj-pci-$(CONFIG_ARCH_IXDP4XX)		+= ixdp425-pci.o
+ obj-pci-$(CONFIG_MACH_AVILA)		+= avila-pci.o
+ obj-pci-$(CONFIG_MACH_CAMBRIA)		+= cambria-pci.o
+@@ -32,6 +33,7 @@ obj-pci-$(CONFIG_MACH_USR8200)		+= usr82
+ 
+ obj-y	+= common.o
+ 
++obj-$(CONFIG_MACH_AP42X)	+= ap42x-setup.o
+ obj-$(CONFIG_ARCH_IXDP4XX)	+= ixdp425-setup.o
+ obj-$(CONFIG_MACH_AVILA)	+= avila-setup.o
+ obj-$(CONFIG_MACH_CAMBRIA)	+= cambria-setup.o