diff mbox series

[v1,2/5] ixp4xx: Resurrect IXP4xx support using device tree

Message ID 20230619113106.2653595-3-linus.walleij@linaro.org
State Superseded
Headers show
Series Resurrect IXP4xx | expand

Commit Message

Linus Walleij June 19, 2023, 11:31 a.m. UTC
This resurrects the support for IXP4xx using device tree
rather than the old (deleted) board files. The final pieces
of IXP4xx board files were deleted in Linux v5.19.

Ext4 root filesystems on CF and USB are supported by the
default config.

We support these three initial targets:

- The Gateworks Avila GW2348 reference design has 64MB of RAM
  and 32MB of flash and also supports USB and CompactFlash.

- The Gateworks Cambria GW2358 reference design has 128MB of
  RAM and 32MB of flash and also supports USB and CompactFlash.

- The old and stable Linksys NSLU2 works fine as well, albeit
  it only has 32MB of RAM so it has been marked as non-default.
  The 8MB of flash can only fit the kernel, so it has been
  patched to boot from exteral media on USB. I have used
  it successfully as a NAS with ksmbd and LUCI web API, see:
  https://dflund.se/~triad/krad/ixp4xx/

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 package/firmware/ixp4xx-microcode/Makefile    |  59 +++++
 .../ixp4xx-microcode/src/IxNpeMicrocode.h     | 148 +++++++++++
 .../firmware/ixp4xx-microcode/src/LICENSE.IPL |  27 ++
 target/linux/ixp4xx/Makefile                  |  28 ++
 .../ixp4xx/base-files/etc/board.d/02_network  |  21 ++
 .../lib/preinit/05_set_ether_mac_ixp4xx       |  45 ++++
 target/linux/ixp4xx/config-6.1                | 246 ++++++++++++++++++
 target/linux/ixp4xx/image/Makefile            |  73 ++++++
 ...d-cfi_cmdset_0001-Byte-swap-OTP-info.patch |  74 ++++++
 ...dts-ixp4xx-Boot-NSLU2-from-harddrive.patch |  24 ++
 10 files changed, 745 insertions(+)
 create mode 100644 package/firmware/ixp4xx-microcode/Makefile
 create mode 100644 package/firmware/ixp4xx-microcode/src/IxNpeMicrocode.h
 create mode 100644 package/firmware/ixp4xx-microcode/src/LICENSE.IPL
 create mode 100644 target/linux/ixp4xx/Makefile
 create mode 100644 target/linux/ixp4xx/base-files/etc/board.d/02_network
 create mode 100644 target/linux/ixp4xx/base-files/lib/preinit/05_set_ether_mac_ixp4xx
 create mode 100644 target/linux/ixp4xx/config-6.1
 create mode 100644 target/linux/ixp4xx/image/Makefile
 create mode 100644 target/linux/ixp4xx/patches-6.1/0001-mtd-cfi_cmdset_0001-Byte-swap-OTP-info.patch
 create mode 100644 target/linux/ixp4xx/patches-6.1/301-ARM-dts-ixp4xx-Boot-NSLU2-from-harddrive.patch

Comments

Hauke Mehrtens Aug. 11, 2023, 2:27 p.m. UTC | #1
On 6/19/23 13:31, Linus Walleij wrote:
> This resurrects the support for IXP4xx using device tree
> rather than the old (deleted) board files. The final pieces
> of IXP4xx board files were deleted in Linux v5.19.
> 
> Ext4 root filesystems on CF and USB are supported by the
> default config.
> 
> We support these three initial targets:
> 
> - The Gateworks Avila GW2348 reference design has 64MB of RAM
>    and 32MB of flash and also supports USB and CompactFlash.
> 
> - The Gateworks Cambria GW2358 reference design has 128MB of
>    RAM and 32MB of flash and also supports USB and CompactFlash.
> 
> - The old and stable Linksys NSLU2 works fine as well, albeit
>    it only has 32MB of RAM so it has been marked as non-default.
>    The 8MB of flash can only fit the kernel, so it has been
>    patched to boot from exteral media on USB. I have used
>    it successfully as a NAS with ksmbd and LUCI web API, see:
>    https://dflund.se/~triad/krad/ixp4xx/
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>   package/firmware/ixp4xx-microcode/Makefile    |  59 +++++
>   .../ixp4xx-microcode/src/IxNpeMicrocode.h     | 148 +++++++++++
>   .../firmware/ixp4xx-microcode/src/LICENSE.IPL |  27 ++
>   target/linux/ixp4xx/Makefile                  |  28 ++
>   .../ixp4xx/base-files/etc/board.d/02_network  |  21 ++
>   .../lib/preinit/05_set_ether_mac_ixp4xx       |  45 ++++
>   target/linux/ixp4xx/config-6.1                | 246 ++++++++++++++++++
>   target/linux/ixp4xx/image/Makefile            |  73 ++++++
>   ...d-cfi_cmdset_0001-Byte-swap-OTP-info.patch |  74 ++++++
>   ...dts-ixp4xx-Boot-NSLU2-from-harddrive.patch |  24 ++
>   10 files changed, 745 insertions(+)
>   create mode 100644 package/firmware/ixp4xx-microcode/Makefile
>   create mode 100644 package/firmware/ixp4xx-microcode/src/IxNpeMicrocode.h
>   create mode 100644 package/firmware/ixp4xx-microcode/src/LICENSE.IPL
>   create mode 100644 target/linux/ixp4xx/Makefile
>   create mode 100644 target/linux/ixp4xx/base-files/etc/board.d/02_network
>   create mode 100644 target/linux/ixp4xx/base-files/lib/preinit/05_set_ether_mac_ixp4xx
>   create mode 100644 target/linux/ixp4xx/config-6.1
>   create mode 100644 target/linux/ixp4xx/image/Makefile
>   create mode 100644 target/linux/ixp4xx/patches-6.1/0001-mtd-cfi_cmdset_0001-Byte-swap-OTP-info.patch
>   create mode 100644 target/linux/ixp4xx/patches-6.1/301-ARM-dts-ixp4xx-Boot-NSLU2-from-harddrive.patch
> 
> diff --git a/package/firmware/ixp4xx-microcode/Makefile b/package/firmware/ixp4xx-microcode/Makefile
> new file mode 100644
> index 000000000000..78fedfd1aaf1
> --- /dev/null
> +++ b/package/firmware/ixp4xx-microcode/Makefile
> @@ -0,0 +1,59 @@
> +#
> +# Copyright (C) 2007 OpenWrt.org
> +#
> +# This is free software, licensed under the GNU General Public License v2.
> +# See /LICENSE for more information.
> +#

Please add a SPDX header and remove the OpenWrt copyright.

> +
> +include $(TOPDIR)/rules.mk
> +
> +PKG_NAME:=ixp4xx-microcode
> +PKG_VERSION:=2.4 > +PKG_RELEASE:=2

Start with pkg release 1

> +
> +PKG_SOURCE:=IPL_ixp400NpeLibraryWithCrypto-2_4.zip
> +PKG_SOURCE_URL:=http://downloads.openwrt.org/sources
> +PKG_HASH:=1b1170d0657847248589d946048c0aeaa9cd671966fc5bec5933283309485eaa
> +
> +PKG_FLAGS:=nonshared
> +
> +include $(INCLUDE_DIR)/package.mk
> +
> +define Package/ixp4xx-microcode
> +  SECTION:=net
> +  CATEGORY:=Network
> +  TITLE:=Microcode for the IXP4xx network engines
> +  DEPENDS:=@TARGET_ixp4xx
> +endef
> +
> +define Package/ixp4xx-microcode/description
> + This package contains the microcode needed to use the network engines in IXP4xx CPUs
> +endef
> +
> +define Build/Prepare
> +	rm -rf $(PKG_BUILD_DIR)
> +	mkdir -p $(PKG_BUILD_DIR)
> +	unzip -d $(PKG_BUILD_DIR)/ $(DL_DIR)/$(PKG_SOURCE)
> +	mv $(PKG_BUILD_DIR)/ixp400_xscale_sw/src/npeDl/IxNpeMicrocode.c $(PKG_BUILD_DIR)/
> +	rm -rf $(PKG_BUILD_DIR)/ixp400_xscale_sw
> +	$(CP) ./src/* $(PKG_BUILD_DIR)/
> +endef
> +
> +define Build/Compile
> +	(cd $(PKG_BUILD_DIR); \
> +		$(HOSTCC) -Wall -I$(STAGING_DIR_HOST)/include IxNpeMicrocode.c -o IxNpeMicrocode; \
> +		./IxNpeMicrocode -be \
> +	)
> +endef
> +
> +define Package/ixp4xx-microcode/install
> +	$(INSTALL_DIR) $(1)/lib/firmware
> +	$(INSTALL_DIR) $(1)/usr/share/doc
> +	$(INSTALL_BIN) $(PKG_BUILD_DIR)/NPE-A $(1)/lib/firmware/
> +	$(INSTALL_BIN) $(PKG_BUILD_DIR)/NPE-A-HSS $(1)/lib/firmware/
> +	$(INSTALL_BIN) $(PKG_BUILD_DIR)/NPE-B $(1)/lib/firmware/
> +	$(INSTALL_BIN) $(PKG_BUILD_DIR)/NPE-C $(1)/lib/firmware/

Are all these FW files always needed, or do you need them depending on 
the use case or device? If they are not always needed maybe add them 
into seperate packages.

> +	$(INSTALL_DATA) $(PKG_BUILD_DIR)/LICENSE.IPL $(1)/usr/share/doc/
> +endef
> +
> +$(eval $(call BuildPackage,ixp4xx-microcode))

....

> diff --git a/target/linux/ixp4xx/Makefile b/target/linux/ixp4xx/Makefile
> new file mode 100644
> index 000000000000..546964a6a876
> --- /dev/null
> +++ b/target/linux/ixp4xx/Makefile
> @@ -0,0 +1,28 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Copyright (C) 2006-2023 OpenWrt.org
> +
> +include $(TOPDIR)/rules.mk
> +
> +ARCH:=armeb
> +BOARD:=ixp4xx
> +BOARDNAME:=Intel XScale IXP4xx
> +FEATURES:=dt squashfs gpio
> +CPU_TYPE:=xscale
> +
> +KERNEL_PATCHVER:=6.1
> +
> +define Target/Description
> +	Build firmware images for the IXP4xx XScale CPU
> +endef
> +
> +KERNELNAME:=zImage dtbs
> +
> +include $(INCLUDE_DIR)/target.mk
> +
> +DEFAULT_PACKAGES += ixp4xx-microcode \
> +	fconfig \
> +	kmod-usb-ledtrig-usbport \
> +	kmod-leds-gpio
> +
> +$(eval $(call BuildTarget))
> diff --git a/target/linux/ixp4xx/base-files/etc/board.d/02_network b/target/linux/ixp4xx/base-files/etc/board.d/02_network
> new file mode 100644
> index 000000000000..45d7cbc75a4a
> --- /dev/null
> +++ b/target/linux/ixp4xx/base-files/etc/board.d/02_network
> @@ -0,0 +1,21 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +. /lib/functions/uci-defaults.sh
> +
> +board_config_update
> +
> +case "$(board_name)" in
> +gateworks,gw2348|\
> +gateworks,gw2358)
> +	ucidef_set_interfaces_lan_wan "eth0" "eth1"
> +	;;
> +linksys,nslu2)
> +	ucidef_set_interface_lan "eth0" "dhcp"
> +	;;
> +*)
> +	ucidef_set_interface_lan "eth0" "dhcp"
> +	;;
> +esac
> +
> +board_config_flush
> +
> +exit 0
> 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
> new file mode 100644
> index 000000000000..fcfd36541e0f
> --- /dev/null
> +++ b/target/linux/ixp4xx/base-files/lib/preinit/05_set_ether_mac_ixp4xx
> @@ -0,0 +1,45 @@
> +#!/bin/sh
> +. /lib/functions.sh
> +. /lib/functions/system.sh
> +
> +set_from_redboot () {
> +	for npe in eth0 eth1 eth2
> +	do
> +		if [ "$(ifconfig $npe 2>/dev/null | grep -c 00:00:00:00:00:00)" = "1" ]; then
> +			ip link set dev $npe address $(fconfig -s -r -d /dev/$1 -n npe_"$npe"_esa)
> +		fi
> +	done
> +
> +	# -- Fixup for the WG302v1, need someone with a WAG302v1 to fix that, too
> +
> +	if [ "$(ifconfig eth0 2>/dev/null | grep -c 00:00:00:00:00:00)" = "1" ]; then
> +			ip link set dev $npe address $(fconfig -s -r -d /dev/$1 -n zcom_npe_esa)
> +	fi
> +
> +	# Others (*cough*, Tonze) are not handling mac addresses at all
> +
> +	if [ "$(ifconfig eth0 2>/dev/null | grep -c 00:00:00:00:00:00)" = "1" ]; then
> +		ip link set dev eth0 address 00:11:22:33:44:55
> +	fi
> +	if [ "$(ifconfig eth1 2>/dev/null | grep -c 00:00:00:00:00:00)" = "1" ]; then
> +		ip link set dev eth0 address 00:11:22:33:44:56
> +	fi

Do you still have the fconfig tool which access something in /dev/ to 
get the mac addresses? Maybe remove the workarounds for devices which 
are not yet supported.

> +}
> +
> +set_from_sysconf () {
> +	ip link set dev eth0 address $(mtd_get_mac_ascii SysConf hw_addr)
> +}
> +
> +set_ether_mac () {
> +	RBC="$(grep "RedBoot config" /proc/mtd | cut -d: -f1)"
> +	if [ ! -z $RBC ] ; then
> +		set_from_redboot $RBC
> +	else
> +		SYSC="$(grep "SysConf" /proc/mtd | cut -d: -f1)"
> +		if [ ! -z $SYSC ] ; then
> +			set_from_sysconf
> +		fi
> +	fi
> +}
> +
> +boot_hook_add preinit_main set_ether_mac



> diff --git a/target/linux/ixp4xx/config-6.1 b/target/linux/ixp4xx/config-6.1
> new file mode 100644
> index 000000000000..ab696fe22ddc
> --- /dev/null
> +++ b/target/linux/ixp4xx/config-6.1
> @@ -0,0 +1,246 @@
> +CONFIG_ALIGNMENT_TRAP=y
> +CONFIG_ARCH_32BIT_OFF_T=y
> +CONFIG_ARCH_FORCE_MAX_ORDER=11
> +CONFIG_ARCH_HIBERNATION_POSSIBLE=y
> +CONFIG_ARCH_IXP4XX=y
> +CONFIG_ARCH_KEEP_MEMBLOCK=y
> +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
> +# CONFIG_ARCH_MULTI_V4 is not set
> +# CONFIG_ARCH_MULTI_V4T is not set
> +CONFIG_ARCH_MULTIPLATFORM=y
> +CONFIG_ARCH_NO_SG_CHAIN=y
> +CONFIG_ARCH_NR_GPIO=0
> +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
> +# CONFIG_ARCH_PRPMC1100 is not set
> +CONFIG_ARCH_SUSPEND_POSSIBLE=y
> +CONFIG_ARM=y
> +CONFIG_ARM_APPENDED_DTB=y
> +# CONFIG_ARM_ATAG_DTB_COMPAT is not set
> +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND=y
> +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
> +CONFIG_ARM_L1_CACHE_SHIFT=5
> +CONFIG_ARM_PATCH_PHYS_VIRT=y
> +CONFIG_ARM_THUMB=y
> +CONFIG_ARM_UNWIND=y
> +CONFIG_ATA=y
> +CONFIG_ATAGS=y
> +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
> +CONFIG_BLK_DEV_SD=y
> +CONFIG_BLK_MQ_PCI=y
> +CONFIG_BOUNCE=y
> +CONFIG_CLKDEV_LOOKUP=y
> +CONFIG_CLKSRC_MMIO=y
> +CONFIG_CLONE_BACKWARDS=y
> +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set
> +CONFIG_COMMON_CLK=y
> +CONFIG_COMPAT_32BIT_TIME=y
> +CONFIG_CPU_32v5=y
> +CONFIG_CPU_ABRT_EV5T=y
> +CONFIG_CPU_BIG_ENDIAN=y
> +CONFIG_CPU_CACHE_VIVT=y
> +CONFIG_CPU_CP15=y
> +CONFIG_CPU_CP15_MMU=y
> +CONFIG_CPU_ENDIAN_BE32=y
> +CONFIG_CPU_PABRT_LEGACY=y
> +CONFIG_CPU_THUMB_CAPABLE=y
> +CONFIG_CPU_TLB_V4WBI=y
> +CONFIG_CPU_USE_DOMAINS=y
> +CONFIG_CPU_XSCALE=y
> +CONFIG_CRYPTO_DEV_IXP4XX=m
> +CONFIG_CRYPTO_HW=y
> +CONFIG_CRYPTO_RNG2=y
> +CONFIG_DEBUG_BUGVERBOSE=y
> +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
> +CONFIG_DEBUG_UART_8250=y
> +CONFIG_DEBUG_UART_8250_SHIFT=2
> +CONFIG_DEBUG_UART_PHYS=0xc8000003
> +CONFIG_DEBUG_UART_VIRT=0xfec00003
> +CONFIG_DMABOUNCE=y
> +CONFIG_DMA_OPS=y
> +CONFIG_DMA_REMAP=y
> +CONFIG_DNOTIFY=y

Do you need CONFIG_DNOTIFY  for something target speicfic?

> +CONFIG_DTC=y
> +CONFIG_EDAC_ATOMIC_SCRUB=y
> +CONFIG_EDAC_SUPPORT=y
> +CONFIG_EEPROM_AT24=y
> +# CONFIG_EEPROM_LEGACY is not set
> +CONFIG_EXT2_FS=y
> +CONFIG_EXT2_FS_XATTR=y
> +CONFIG_EXT2_FS_POSIX_ACL=y
> +# CONFIG_EXT2_FS_SECURITY is not set
> +CONFIG_EXT3_FS=y
> +CONFIG_EXT3_FS_POSIX_ACL=y
> +# CONFIG_EXT3_FS_SECURITY is not set

Ext4 should be sufficent it can handle ext2 and ext3 too.

> +CONFIG_EXT4_FS=y
> +CONFIG_EXT4_FS_POSIX_ACL=y
> +# CONFIG_EXT4_FS_SECURITY is not set

"# CONFIG_EXT4_FS_SECURITY is not set" is already set in the generic 
configuration. have you run:
make kernel_oldconfig

> +# CONFIG_FARSYNC is not set
> +CONFIG_FIXED_PHY=y
> +CONFIG_FIX_EARLYCON_MEM=y
> +CONFIG_FORCE_PCI=y
> +CONFIG_FW_LOADER_PAGED_BUF=y
> +CONFIG_GENERIC_ALLOCATOR=y
> +CONFIG_GENERIC_ATOMIC64=y
> +CONFIG_GENERIC_BUG=y
> +CONFIG_GENERIC_CLOCKEVENTS=y
> +CONFIG_GENERIC_CPU_AUTOPROBE=y
> +CONFIG_GENERIC_EARLY_IOREMAP=y
> +CONFIG_GENERIC_IDLE_POLL_SETUP=y
> +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
> +CONFIG_GENERIC_IRQ_SHOW=y
> +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
> +CONFIG_GENERIC_PCI_IOMAP=y
> +CONFIG_GENERIC_SCHED_CLOCK=y
> +CONFIG_GENERIC_SMP_IDLE_THREAD=y
> +CONFIG_GENERIC_STRNCPY_FROM_USER=y
> +CONFIG_GENERIC_STRNLEN_USER=y
> +CONFIG_GPIOLIB=y
> +CONFIG_GPIOLIB_IRQCHIP=y
> +CONFIG_GPIO_GENERIC=y
> +CONFIG_GPIO_GW_PLD=y
> +CONFIG_GPIO_IXP4XX=y
> +CONFIG_HANDLE_DOMAIN_IRQ=y
> +CONFIG_HARDIRQS_SW_RESEND=y
> +CONFIG_HAS_DMA=y
> +CONFIG_HAS_IOMEM=y
> +CONFIG_HAS_IOPORT_MAP=y
> +CONFIG_HDLC=y
> +CONFIG_HWMON=y
> +CONFIG_HWMON_VID=y
> +CONFIG_HW_RANDOM=y
> +CONFIG_HW_RANDOM_IXP4XX=y
> +CONFIG_HZ=100
> +CONFIG_HZ_100=y
> +CONFIG_HZ_FIXED=0
> +CONFIG_HZ_PERIODIC=y
> +CONFIG_I2C=y
> +CONFIG_I2C_ALGOBIT=y
> +CONFIG_I2C_BOARDINFO=y
> +CONFIG_I2C_CHARDEV=y
> +CONFIG_I2C_GPIO=y
> +CONFIG_I2C_IOP3XX=y
> +CONFIG_INITRAMFS_SOURCE=""
> +CONFIG_INPUT_GPIO_BEEPER=y
> +CONFIG_INPUT_MISC=y
> +CONFIG_INTEL_IXP4XX_EB=y
> +CONFIG_IRQCHIP=y
> +CONFIG_IRQ_DOMAIN=y
> +CONFIG_IRQ_DOMAIN_HIERARCHY=y
> +CONFIG_IRQ_FORCED_THREADING=y
> +CONFIG_IRQ_WORK=y
> +# CONFIG_IWMMXT is not set
> +CONFIG_IXP4XX_ETH=y
> +# CONFIG_IXP4XX_INDIRECT_PCI is not set
> +CONFIG_IXP4XX_HSS=y
> +CONFIG_IXP4XX_IRQ=y
> +CONFIG_IXP4XX_NPE=y
> +# CONFIG_IXP4XX_PCI_LEGACY is not set
> +CONFIG_IXP4XX_QMGR=y
> +CONFIG_IXP4XX_TIMER=y
> +CONFIG_IXP4XX_WATCHDOG=y
> +CONFIG_LEDS_GPIO=y
> +CONFIG_LEGACY_PTYS=y
> +CONFIG_LEGACY_PTY_COUNT=256
> +CONFIG_LIBFDT=y
> +CONFIG_LLD_VERSION=0
> +CONFIG_LOCK_DEBUGGING_SUPPORT=y
> +CONFIG_MDIO_BUS=y
> +CONFIG_MDIO_DEVICE=y
> +CONFIG_MDIO_DEVRES=y
> +CONFIG_MEMFD_CREATE=y
> +CONFIG_MIGRATION=y
> +CONFIG_MODULES_USE_ELF_REL=y
> +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_PHYSMAP_OF=y
> +CONFIG_MTD_PHYSMAP_IXP4XX=y
> +CONFIG_MTD_REDBOOT_PARTS=y
> +CONFIG_MTD_SPLIT_FIRMWARE=y
> +CONFIG_MTD_SPLIT_FIRMWARE_NAME="linux"
> +CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y
> +CONFIG_NEED_DMA_MAP_STATE=y
> +CONFIG_NEED_KUSER_HELPERS=y
> +CONFIG_NEED_MACH_IO_H=y
> +CONFIG_NEED_PER_CPU_KM=y
> +CONFIG_NET_PTP_CLASSIFY=y
> +CONFIG_NET_VENDOR_XSCALE=y
> +CONFIG_NVMEM=y
> +CONFIG_NVMEM_SYSFS=y
> +CONFIG_OF=y
> +CONFIG_OF_ADDRESS=y
> +CONFIG_OF_EARLY_FLATTREE=y
> +CONFIG_OF_FLATTREE=y
> +CONFIG_OF_GPIO=y
> +CONFIG_OF_IRQ=y
> +CONFIG_OF_KOBJ=y
> +CONFIG_OF_MDIO=y
> +CONFIG_OF_NET=y
> +CONFIG_OLD_SIGACTION=y
> +CONFIG_OLD_SIGSUSPEND3=y

I think these 2 old syscalls are not needed.

> +CONFIG_PAGE_OFFSET=0xC0000000
> +CONFIG_PATA_IXP4XX_CF=y
> +CONFIG_PCI=y
> +CONFIG_PCI_IXP4XX=y
> +CONFIG_PERF_USE_VMALLOC=y
> +CONFIG_PGTABLE_LEVELS=2
> +CONFIG_PHYLIB=y
> +CONFIG_PHYS_OFFSET=0
> +CONFIG_POWER_RESET=y
> +CONFIG_POWER_RESET_GPIO=y
> +CONFIG_RATIONAL=y
> +CONFIG_REGMAP=y
> +CONFIG_REGMAP_I2C=y
> +CONFIG_RTC_CLASS=y
> +CONFIG_RTC_DRV_DS1672=y
> +CONFIG_RTC_DRV_ISL1208=y
> +CONFIG_RTC_DRV_PCF8563=y
> +CONFIG_RTC_DRV_X1205=y
> +CONFIG_RTC_I2C_AND_SPI=y
> +CONFIG_RTC_MC146818_LIB=y

Do you need all these RTC clocks compiled into the kernel image?

> +CONFIG_SENSORS_AD7418=y
> +CONFIG_SENSORS_MAX6650=y
> +CONFIG_SENSORS_W83781D=y

Do you need all these sensors compiled into the kernel image?

> +CONFIG_SERIAL_8250_EXAR=y
> +CONFIG_SERIAL_8250_FSL=y
> +CONFIG_SERIAL_8250_NR_UARTS=2
> +CONFIG_SERIAL_8250_PCI=y
> +CONFIG_SERIAL_8250_PERICOM=y
> +CONFIG_SERIAL_8250_RUNTIME_UARTS=2
> +CONFIG_SERIAL_MCTRL_GPIO=y
> +CONFIG_SERIAL_OF_PLATFORM=y
> +CONFIG_SPARSE_IRQ=y
> +CONFIG_SPLIT_PTLOCK_CPUS=999999
> +CONFIG_SRCU=y
> +CONFIG_SWPHY=y
> +CONFIG_SYS_SUPPORTS_APM_EMULATION=y
> +CONFIG_TICK_CPU_ACCOUNTING=y
> +CONFIG_TIMER_OF=y
> +CONFIG_TIMER_PROBE=y
> +CONFIG_TINY_SRCU=y
> +CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
> +CONFIG_UNWINDER_ARM=y
> +# CONFIG_UNUSED_BOARD_FILES is not set
> +CONFIG_USB=y
> +CONFIG_USB_COMMON=y
> +CONFIG_USB_EHCI_BIG_ENDIAN_DESC=y
> +CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
> +CONFIG_USB_EHCI_HCD=y
> +CONFIG_USB_EHCI_PCI=y
> +CONFIG_USB_EHCI_TT_NEWSCHED=y
> +CONFIG_USB_OHCI_HCD=y
> +CONFIG_USB_OHCI_HCD_PCI=y
> +# CONFIG_USB_OHCI_HCD_PLATFORM is not set
> +CONFIG_USB_PCI=y
> +CONFIG_USB_STORAGE=y
> +CONFIG_USB_SUPPORT=y
> +CONFIG_USE_OF=y
> +CONFIG_VM_EVENT_COUNTERS=y
> +CONFIG_WAN=y
> +CONFIG_WATCHDOG_NOWAYOUT=y
> +CONFIG_XZ_DEC_ARM=y
> +CONFIG_XZ_DEC_BCJ=y
> +CONFIG_ZBOOT_ROM_BSS=0x0
> +CONFIG_ZBOOT_ROM_TEXT=0x0
> diff --git a/target/linux/ixp4xx/image/Makefile b/target/linux/ixp4xx/image/Makefile
> new file mode 100644
> index 000000000000..73e0984f638c
> --- /dev/null
> +++ b/target/linux/ixp4xx/image/Makefile
> @@ -0,0 +1,73 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Copyright (C) 2006-2021 OpenWrt.org
> +
> +include $(TOPDIR)/rules.mk
> +include $(INCLUDE_DIR)/image.mk
> +
> +# Cook a Linksys NSLU2 etc image
> +define Build/linksys-ixp425-image
> +	touch $@.null-initrd
> +	$(TOPDIR)/scripts/slugimage.pl -L $(STAGING_DIR_IMAGE)/apex-$(1)-armeb.bin -k $@ -r $@.null-initrd -p -o $@.new
> +	mv $@.new $@
> +endef
> +
> +# Build sysupgrade image
> +define BuildFirmware/Generic
> +	dd if=$(KDIR)/zImage of=$(KDIR)/zImage.pad bs=64k conv=sync; \
> +	dd if=$(KDIR)/root.$(1) of=$(KDIR)/root.$(1).pad bs=128k conv=sync; \
> +	sh $(TOPDIR)/scripts/combined-image.sh \
> +		$(KDIR)/zImage.pad \
> +		$(KDIR)/root.$(1).pad \
> +		$(BIN_DIR)/$(IMG_PREFIX)-$(patsubst jffs2-%,jffs2,$(patsubst squashfs-%,squashfs,$(1)))-sysupgrade.bin
> +endef
> +
> +define Image/Build
> +	$(call Image/Build/$(1),$(1))
> +	$(call BuildFirmware/Generic,$(1))
> +endef
> +
> +define Device/Default
> +	PROFILES := Default
> +	KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
> +	KERNEL_NAME := zImage
> +	KERNEL := kernel-bin | append-dtb
> +	BLOCKSIZE := 128k
> +endef
> +
> +define Device/avila
> +	DEVICE_VENDOR := Gateway
> +	DEVICE_MODEL := Avila GW2348-4
> +	DEVICE_DTS := intel-ixp42x-gateworks-gw2348
> +	KERNEL := kernel-bin | append-dtb
> +	IMAGES := kernel.bin rootfs.bin
> +	IMAGE/kernel.bin := append-kernel
> +	IMAGE/rootfs.bin := append-rootfs | pad-rootfs | pad-to 128k
> +endef
> +TARGET_DEVICES += avila
> +
> +define Device/cambria
> +	DEVICE_VENDOR := Gateway
> +	DEVICE_MODEL := Cambria GW2358-4
> +	DEVICE_DTS := intel-ixp43x-gateworks-gw2358
> +	KERNEL := kernel-bin | append-dtb
> +	IMAGES := kernel.bin rootfs.bin
> +	IMAGE/kernel.bin := append-kernel
> +	IMAGE/rootfs.bin := append-rootfs | pad-rootfs | pad-to 128k
> +endef
> +TARGET_DEVICES += cambria
> +
> +define Device/nslu2
> +	DEVICE_VENDOR := Linksys
> +	DEVICE_MODEL := NSLU2
> +	# Only 32 MB of RAM so not building by default
> +	DEFAULT := n
> +	DEVICE_DTS := intel-ixp42x-linksys-nslu2
> +	KERNEL := kernel-bin | append-dtb
> +	IMAGES := factory.bin
> +	# This has to boot from harddisk so just append the kernel
> +	IMAGE/factory.bin := append-kernel | linksys-ixp425-image "nslu2"
> +endef
> +TARGET_DEVICES += nslu2
> +
> +$(eval $(call BuildImage))
> diff --git a/target/linux/ixp4xx/patches-6.1/0001-mtd-cfi_cmdset_0001-Byte-swap-OTP-info.patch b/target/linux/ixp4xx/patches-6.1/0001-mtd-cfi_cmdset_0001-Byte-swap-OTP-info.patch
> new file mode 100644
> index 000000000000..1c5e44bb7240
> --- /dev/null
> +++ b/target/linux/ixp4xx/patches-6.1/0001-mtd-cfi_cmdset_0001-Byte-swap-OTP-info.patch
> @@ -0,0 +1,74 @@
> +From 4e242d6e08ad1d85b832e158cd0eafcb8f3f76a1 Mon Sep 17 00:00:00 2001
> +From: Linus Walleij <linus.walleij@linaro.org>
> +Date: Tue, 30 May 2023 22:40:31 +0200
> +Subject: [PATCH v3] mtd: cfi_cmdset_0001: Byte swap OTP info
> +
> +Currently the offset into the device when looking for OTP
> +bits can go outside of the address of the MTD NOR devices,
> +and if that memory isn't readable, bad things happen
> +on the IXP4xx (added prints that illustrate the problem before
> +the crash):
> +
> +cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x00000100
> +ixp4xx_copy_from copy from 0x00000100 to 0xc880dd78
> +cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x12000000
> +ixp4xx_copy_from copy from 0x12000000 to 0xc880dd78
> +8<--- cut here ---
> +Unable to handle kernel paging request at virtual address db000000
> +[db000000] *pgd=00000000
> +(...)
> +
> +This happens in this case because the IXP4xx is big endian and
> +the 32- and 16-bit fields in the struct cfi_intelext_otpinfo are not
> +properly byteswapped. Compare to how the code in read_pri_intelext()
> +byteswaps the fields in struct cfi_pri_intelext.
> +
> +Adding a small byte swapping loop for the OTP in read_pri_intelext()
> +and the crash goes away.
> +
> +The problem went unnoticed for many years until I enabled
> +CONFIG_MTD_OTP on the IXP4xx as well, triggering the bug.
> +
> +Cc: Nicolas Pitre <npitre@baylibre.com>
> +Cc: stable@vger.kernel.org
> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> +---
> +ChangeLog v2->v3:
> +- Move the byte swapping to a small loop in read_pri_intelext()
> +  so all bytes are swapped as we reach cfi_intelext_otp_walk().
> +ChangeLog v1->v2:
> +- Drill deeper and discover a big endian compatibility issue.
> +---
> + drivers/mtd/chips/cfi_cmdset_0001.c | 20 ++++++++++++++++++--
> + 1 file changed, 18 insertions(+), 2 deletions(-)
> +
> +--- a/drivers/mtd/chips/cfi_cmdset_0001.c
> ++++ b/drivers/mtd/chips/cfi_cmdset_0001.c
> +@@ -421,9 +421,25 @@ read_pri_intelext(struct map_info *map,
> + 		extra_size = 0;
> +
> + 		/* Protection Register info */
> +-		if (extp->NumProtectionFields)
> ++		if (extp->NumProtectionFields) {
> ++			struct cfi_intelext_otpinfo *otp =
> ++				(struct cfi_intelext_otpinfo *)&extp->extra[0];
> ++
> + 			extra_size += (extp->NumProtectionFields - 1) *
> +-				      sizeof(struct cfi_intelext_otpinfo);
> ++				sizeof(struct cfi_intelext_otpinfo);
> ++
> ++			if (extp_size >= sizeof(*extp) + extra_size) {
> ++				int i;
> ++
> ++				/* Do some byteswapping if necessary */
> ++				for (i = 0; i < extp->NumProtectionFields - 1; i++) {
> ++					otp->ProtRegAddr = le32_to_cpu(otp->ProtRegAddr);
> ++					otp->FactGroups = le16_to_cpu(otp->FactGroups);
> ++					otp->UserGroups = le16_to_cpu(otp->UserGroups);
> ++					otp++;
> ++				}
> ++			}
> ++		}
> + 	}
> +
> + 	if (extp->MinorVersion >= '1') {
> diff --git a/target/linux/ixp4xx/patches-6.1/301-ARM-dts-ixp4xx-Boot-NSLU2-from-harddrive.patch b/target/linux/ixp4xx/patches-6.1/301-ARM-dts-ixp4xx-Boot-NSLU2-from-harddrive.patch
> new file mode 100644
> index 000000000000..ffd69a774c3c
> --- /dev/null
> +++ b/target/linux/ixp4xx/patches-6.1/301-ARM-dts-ixp4xx-Boot-NSLU2-from-harddrive.patch
> @@ -0,0 +1,24 @@
> +From 2792791a19f90b0141ed2e781599ba0a42a8cfd5 Mon Sep 17 00:00:00 2001
> +From: Linus Walleij <linus.walleij@linaro.org>
> +Date: Mon, 29 May 2023 23:32:44 +0200
> +Subject: [PATCH] ARM: dts: ixp4xx: Boot NSLU2 from harddrive
> +
> +This enforces harddrive boot on the NSLU2. The flash is too small
> +to hold any rootfs these days.
> +
> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> +---
> + arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts | 2 +-
> + 1 file changed, 1 insertion(+), 1 deletion(-)
> +
> +--- a/arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts
> ++++ b/arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts
> +@@ -21,7 +21,7 @@
> + 	};
> +
> + 	chosen {
> +-		bootargs = "console=ttyS0,115200n8 root=/dev/mtdblock2 rw rootfstype=squashfs,jffs2 rootwait";
> ++		bootargs = "console=ttyS0,115200n8 root=/dev/sda1 rw rootwait";
> + 		stdout-path = "uart0:115200n8";
> + 	};
> +
Linus Walleij Aug. 17, 2023, 7:43 a.m. UTC | #2
Thanks for reviewing this Hauke!

I fixed most things, will post v2 as time permits.

On Fri, Aug 11, 2023 at 4:27 PM Hauke Mehrtens <hauke@hauke-m.de> wrote:

> Do you still have the fconfig tool which access something in /dev/ to
> get the mac addresses?

Yes it was one of the leftovers that just stayed around after the
removal of the unmaintained ixp4xx boardfile machines. So I
just select it from the top-level makefile and things work fine.

Another thing left behind was the python build script for NSLU2
images.

But I needed them so it's all good when we bring IXP4xx back.
(Please don't delete them...)

I deleted one minor useless script though (patch 5).

Yours,
Linus Walleij
diff mbox series

Patch

diff --git a/package/firmware/ixp4xx-microcode/Makefile b/package/firmware/ixp4xx-microcode/Makefile
new file mode 100644
index 000000000000..78fedfd1aaf1
--- /dev/null
+++ b/package/firmware/ixp4xx-microcode/Makefile
@@ -0,0 +1,59 @@ 
+#
+# Copyright (C) 2007 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ixp4xx-microcode
+PKG_VERSION:=2.4
+PKG_RELEASE:=2
+
+PKG_SOURCE:=IPL_ixp400NpeLibraryWithCrypto-2_4.zip
+PKG_SOURCE_URL:=http://downloads.openwrt.org/sources
+PKG_HASH:=1b1170d0657847248589d946048c0aeaa9cd671966fc5bec5933283309485eaa
+
+PKG_FLAGS:=nonshared
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ixp4xx-microcode
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Microcode for the IXP4xx network engines
+  DEPENDS:=@TARGET_ixp4xx
+endef
+
+define Package/ixp4xx-microcode/description
+ This package contains the microcode needed to use the network engines in IXP4xx CPUs
+endef
+
+define Build/Prepare
+	rm -rf $(PKG_BUILD_DIR)
+	mkdir -p $(PKG_BUILD_DIR)
+	unzip -d $(PKG_BUILD_DIR)/ $(DL_DIR)/$(PKG_SOURCE)
+	mv $(PKG_BUILD_DIR)/ixp400_xscale_sw/src/npeDl/IxNpeMicrocode.c $(PKG_BUILD_DIR)/
+	rm -rf $(PKG_BUILD_DIR)/ixp400_xscale_sw
+	$(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+	(cd $(PKG_BUILD_DIR); \
+		$(HOSTCC) -Wall -I$(STAGING_DIR_HOST)/include IxNpeMicrocode.c -o IxNpeMicrocode; \
+		./IxNpeMicrocode -be \
+	)
+endef
+
+define Package/ixp4xx-microcode/install
+	$(INSTALL_DIR) $(1)/lib/firmware
+	$(INSTALL_DIR) $(1)/usr/share/doc
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/NPE-A $(1)/lib/firmware/
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/NPE-A-HSS $(1)/lib/firmware/
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/NPE-B $(1)/lib/firmware/
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/NPE-C $(1)/lib/firmware/
+	$(INSTALL_DATA) $(PKG_BUILD_DIR)/LICENSE.IPL $(1)/usr/share/doc/
+endef
+
+$(eval $(call BuildPackage,ixp4xx-microcode))
diff --git a/package/firmware/ixp4xx-microcode/src/IxNpeMicrocode.h b/package/firmware/ixp4xx-microcode/src/IxNpeMicrocode.h
new file mode 100644
index 000000000000..4a843db104f9
--- /dev/null
+++ b/package/firmware/ixp4xx-microcode/src/IxNpeMicrocode.h
@@ -0,0 +1,148 @@ 
+/*
+ * IxNpeMicrocode.h - Headerfile for compiling the Intel microcode C file
+ *
+ * Copyright (C) 2006 Christian Hohnstaedt <chohnstaedt@innominate.com>
+ *
+ * This file is released under the GPLv2
+ *
+ *
+ * compile with
+ *
+ * gcc -Wall IxNpeMicrocode.c -o IxNpeMicrocode
+ *
+ * Executing the resulting binary on your build-host creates the
+ * "NPE-[ABC].xxxxxxxx" files containing the selected microcode
+ *
+ * fetch the IxNpeMicrocode.c from the Intel Access Library.
+ * It will include this header.
+ *
+ * select Images for every NPE from the following
+ * (used C++ comments for easy uncommenting ....)
+ */
+
+// #define IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_MASK_FIREWALL_VLAN_QOS_HDR_CONV_EXTMIB
+// #define IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_VLAN_QOS_HDR_CONV_EXTMIB
+// #define IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_MASK_FIREWALL_VLAN_QOS_EXTMIB
+// #define IX_NPEDL_NPEIMAGE_NPEA_HSS_TSLOT_SWITCH
+#define IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+// #define IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+// #define IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL
+#define IX_NPEDL_NPEIMAGE_NPEA_HSS_2_PORT
+// #define IX_NPEDL_NPEIMAGE_NPEA_DMA
+// #define IX_NPEDL_NPEIMAGE_NPEA_ATM_MPHY_12_PORT
+// #define IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_MPHY_1_PORT
+// #define IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_SPHY_1_PORT
+// #define IX_NPEDL_NPEIMAGE_NPEA_HSS0
+// #define IX_NPEDL_NPEIMAGE_NPEA_WEP
+
+
+// #define IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_MASK_FIREWALL_VLAN_QOS_HDR_CONV_EXTMIB
+// #define IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_VLAN_QOS_HDR_CONV_EXTMIB
+// #define IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_MASK_FIREWALL_VLAN_QOS_EXTMIB
+// #define IX_NPEDL_NPEIMAGE_NPEB_DMA
+#define IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+// #define IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+// #define IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL
+
+
+// #define IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_MASK_FIREWALL_VLAN_QOS_HDR_CONV_EXTMIB
+// #define IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_VLAN_QOS_HDR_CONV_EXTMIB
+// #define IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_MASK_FIREWALL_VLAN_QOS_EXTMIB
+// #define IX_NPEDL_NPEIMAGE_NPEC_DMA
+// #define IX_NPEDL_NPEIMAGE_NPEC_CRYPTO_AES_ETH_LEARN_FILTER_SPAN
+// #define IX_NPEDL_NPEIMAGE_NPEC_CRYPTO_AES_ETH_LEARN_FILTER_FIREWALL
+#define IX_NPEDL_NPEIMAGE_NPEC_CRYPTO_AES_CCM_ETH
+// #define IX_NPEDL_NPEIMAGE_NPEC_CRYPTO_AES_CCM_EXTSHA_ETH
+// #define IX_NPEDL_NPEIMAGE_NPEC_CRYPTO_ETH_LEARN_FILTER_SPAN_FIREWALL
+// #define IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+// #define IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+// #define IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <string.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define to_le32(x) (x)
+#define to_be32(x) bswap_32(x)
+#else
+#define to_be32(x) (x)
+#define to_le32(x) bswap_32(x)
+#endif
+
+struct dl_image {
+	unsigned magic;
+	unsigned id;
+	unsigned size;
+	unsigned data[0];
+};
+
+const unsigned IxNpeMicrocode_array[];
+
+int main(int argc, char *argv[])
+{
+	struct dl_image *image = (struct dl_image *)IxNpeMicrocode_array;
+	int imgsiz, i, fd, cnt;
+	const unsigned *arrayptr = IxNpeMicrocode_array;
+	const char *names[] = { "IXP425", "IXP465", "unknown" };
+	int bigendian = 1;
+
+	if (argc > 1) {
+		if (!strcmp(argv[1], "-le"))
+			bigendian = 0;
+		else if (!strcmp(argv[1], "-be"))
+			bigendian = 1;
+		else {
+			printf("Usage: %s <-le|-be>\n", argv[0]);
+			return EXIT_FAILURE;
+		}
+	}
+
+	for (image = (struct dl_image *)arrayptr, cnt=0;
+		(image->id != 0xfeedf00d) && (image->magic == 0xfeedf00d);
+		image = (struct dl_image *)(arrayptr), cnt++)
+	{
+		unsigned char field[4];
+		imgsiz = image->size + 3;
+		*(unsigned*)field = to_be32(image->id);
+		char filename[40], slnk[10];
+
+		sprintf(filename, "NPE-%c.%08x", (field[0] & 0xf) + 'A',
+			image->id);
+		if (image->id == 0x00090000)
+			sprintf(slnk, "NPE-%c-HSS", (field[0] & 0xf) + 'A');
+		else
+			sprintf(slnk, "NPE-%c", (field[0] & 0xf) + 'A');
+
+		printf("Writing image: %s.NPE_%c Func: %2x Rev: %02x.%02x "
+			"Size: %5d to: '%s'\n",
+			names[field[0] >> 4], (field[0] & 0xf) + 'A',
+			field[1], field[2], field[3], imgsiz*4, filename);
+		fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, 0644);
+		if (fd >= 0) {
+			for (i=0; i<imgsiz; i++) {
+				*(unsigned*)field = bigendian ?
+					to_be32(arrayptr[i]) :
+					to_le32(arrayptr[i]);
+				write(fd, field, sizeof(field));
+			}
+			close(fd);
+			unlink(slnk);
+			symlink(filename, slnk);
+		} else {
+			perror(filename);
+		}
+		arrayptr += imgsiz;
+	}
+	close(fd);
+	return 0;
+}
diff --git a/package/firmware/ixp4xx-microcode/src/LICENSE.IPL b/package/firmware/ixp4xx-microcode/src/LICENSE.IPL
new file mode 100644
index 000000000000..dad2566cfcaa
--- /dev/null
+++ b/package/firmware/ixp4xx-microcode/src/LICENSE.IPL
@@ -0,0 +1,27 @@ 
+INTEL(R) SOFTWARE LICENSE AGREEMENT
+ 
+Copyright (c) 2007, Intel Corporation.
+All rights reserved.
+
+Redistribution. Redistribution and use in binary form, without modification, are permitted
+provided that the following conditions are met:
+o Redistributions must reproduce the above copyright notice and the following disclaimer in the
+documentation and/or other materials provided with the distribution. 
+o Neither the name of Intel Corporation nor the names of its suppliers may be used to endorse
+or promote products derived from this software without specific prior written permission. 
+o No reverse engineering, decompilation, or disassembly of this software is permitted.
+
+Limited patent license. Intel Corporation grants a world-wide, royalty-free, non-exclusive
+license under patents it now or hereafter owns or controls to make, have made, use, import,
+offer to sell and sell (.Utilize.) this software, but solely to the extent that any such patent is
+necessary to Utilize the software alone. The patent license shall not apply to any combinations
+which include this software. No hardware per se is licensed hereunder.
+DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGE.
diff --git a/target/linux/ixp4xx/Makefile b/target/linux/ixp4xx/Makefile
new file mode 100644
index 000000000000..546964a6a876
--- /dev/null
+++ b/target/linux/ixp4xx/Makefile
@@ -0,0 +1,28 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2006-2023 OpenWrt.org
+
+include $(TOPDIR)/rules.mk
+
+ARCH:=armeb
+BOARD:=ixp4xx
+BOARDNAME:=Intel XScale IXP4xx
+FEATURES:=dt squashfs gpio
+CPU_TYPE:=xscale
+
+KERNEL_PATCHVER:=6.1
+
+define Target/Description
+	Build firmware images for the IXP4xx XScale CPU
+endef
+
+KERNELNAME:=zImage dtbs
+
+include $(INCLUDE_DIR)/target.mk
+
+DEFAULT_PACKAGES += ixp4xx-microcode \
+	fconfig \
+	kmod-usb-ledtrig-usbport \
+	kmod-leds-gpio
+
+$(eval $(call BuildTarget))
diff --git a/target/linux/ixp4xx/base-files/etc/board.d/02_network b/target/linux/ixp4xx/base-files/etc/board.d/02_network
new file mode 100644
index 000000000000..45d7cbc75a4a
--- /dev/null
+++ b/target/linux/ixp4xx/base-files/etc/board.d/02_network
@@ -0,0 +1,21 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+case "$(board_name)" in
+gateworks,gw2348|\
+gateworks,gw2358)
+	ucidef_set_interfaces_lan_wan "eth0" "eth1"
+	;;
+linksys,nslu2)
+	ucidef_set_interface_lan "eth0" "dhcp"
+	;;
+*)
+	ucidef_set_interface_lan "eth0" "dhcp"
+	;;
+esac
+
+board_config_flush
+
+exit 0
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
new file mode 100644
index 000000000000..fcfd36541e0f
--- /dev/null
+++ b/target/linux/ixp4xx/base-files/lib/preinit/05_set_ether_mac_ixp4xx
@@ -0,0 +1,45 @@ 
+#!/bin/sh
+. /lib/functions.sh
+. /lib/functions/system.sh
+
+set_from_redboot () {
+	for npe in eth0 eth1 eth2
+	do
+		if [ "$(ifconfig $npe 2>/dev/null | grep -c 00:00:00:00:00:00)" = "1" ]; then
+			ip link set dev $npe address $(fconfig -s -r -d /dev/$1 -n npe_"$npe"_esa)
+		fi
+	done
+
+	# -- Fixup for the WG302v1, need someone with a WAG302v1 to fix that, too
+
+	if [ "$(ifconfig eth0 2>/dev/null | grep -c 00:00:00:00:00:00)" = "1" ]; then
+			ip link set dev $npe address $(fconfig -s -r -d /dev/$1 -n zcom_npe_esa)
+	fi
+
+	# Others (*cough*, Tonze) are not handling mac addresses at all
+
+	if [ "$(ifconfig eth0 2>/dev/null | grep -c 00:00:00:00:00:00)" = "1" ]; then
+		ip link set dev eth0 address 00:11:22:33:44:55
+	fi
+	if [ "$(ifconfig eth1 2>/dev/null | grep -c 00:00:00:00:00:00)" = "1" ]; then
+		ip link set dev eth0 address 00:11:22:33:44:56
+	fi
+}
+
+set_from_sysconf () {
+	ip link set dev eth0 address $(mtd_get_mac_ascii SysConf hw_addr)
+}
+
+set_ether_mac () {
+	RBC="$(grep "RedBoot config" /proc/mtd | cut -d: -f1)"
+	if [ ! -z $RBC ] ; then
+		set_from_redboot $RBC
+	else
+		SYSC="$(grep "SysConf" /proc/mtd | cut -d: -f1)"
+		if [ ! -z $SYSC ] ; then
+			set_from_sysconf
+		fi
+	fi
+}
+
+boot_hook_add preinit_main set_ether_mac
diff --git a/target/linux/ixp4xx/config-6.1 b/target/linux/ixp4xx/config-6.1
new file mode 100644
index 000000000000..ab696fe22ddc
--- /dev/null
+++ b/target/linux/ixp4xx/config-6.1
@@ -0,0 +1,246 @@ 
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_FORCE_MAX_ORDER=11
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_IXP4XX=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+# CONFIG_ARCH_MULTI_V4 is not set
+# CONFIG_ARCH_MULTI_V4T is not set
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_NO_SG_CHAIN=y
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+# CONFIG_ARCH_PRPMC1100 is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM=y
+CONFIG_ARM_APPENDED_DTB=y
+# CONFIG_ARM_ATAG_DTB_COMPAT is not set
+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND=y
+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ATA=y
+CONFIG_ATAGS=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BOUNCE=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+# CONFIG_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_COMMON_CLK=y
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_ENDIAN_BE32=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_USE_DOMAINS=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CRYPTO_DEV_IXP4XX=m
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
+CONFIG_DEBUG_UART_8250=y
+CONFIG_DEBUG_UART_8250_SHIFT=2
+CONFIG_DEBUG_UART_PHYS=0xc8000003
+CONFIG_DEBUG_UART_VIRT=0xfec00003
+CONFIG_DMABOUNCE=y
+CONFIG_DMA_OPS=y
+CONFIG_DMA_REMAP=y
+CONFIG_DNOTIFY=y
+CONFIG_DTC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_FARSYNC is not set
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FORCE_PCI=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_GW_PLD=y
+CONFIG_GPIO_IXP4XX=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HDLC=y
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_IXP4XX=y
+CONFIG_HZ=100
+CONFIG_HZ_100=y
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_IOP3XX=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT_GPIO_BEEPER=y
+CONFIG_INPUT_MISC=y
+CONFIG_INTEL_IXP4XX_EB=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_IWMMXT is not set
+CONFIG_IXP4XX_ETH=y
+# CONFIG_IXP4XX_INDIRECT_PCI is not set
+CONFIG_IXP4XX_HSS=y
+CONFIG_IXP4XX_IRQ=y
+CONFIG_IXP4XX_NPE=y
+# CONFIG_IXP4XX_PCI_LEGACY is not set
+CONFIG_IXP4XX_QMGR=y
+CONFIG_IXP4XX_TIMER=y
+CONFIG_IXP4XX_WATCHDOG=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_LIBFDT=y
+CONFIG_LLD_VERSION=0
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MIGRATION=y
+CONFIG_MODULES_USE_ELF_REL=y
+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_PHYSMAP_OF=y
+CONFIG_MTD_PHYSMAP_IXP4XX=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_FIRMWARE_NAME="linux"
+CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_KUSER_HELPERS=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_VENDOR_XSCALE=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PATA_IXP4XX_CF=y
+CONFIG_PCI=y
+CONFIG_PCI_IXP4XX=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYS_OFFSET=0
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1672=y
+CONFIG_RTC_DRV_ISL1208=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_X1205=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_SENSORS_AD7418=y
+CONFIG_SENSORS_MAX6650=y
+CONFIG_SENSORS_W83781D=y
+CONFIG_SERIAL_8250_EXAR=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PERICOM=y
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+CONFIG_SRCU=y
+CONFIG_SWPHY=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TINY_SRCU=y
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+# CONFIG_UNUSED_BOARD_FILES is not set
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_PCI=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PCI=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+CONFIG_USB_PCI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_WAN=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
diff --git a/target/linux/ixp4xx/image/Makefile b/target/linux/ixp4xx/image/Makefile
new file mode 100644
index 000000000000..73e0984f638c
--- /dev/null
+++ b/target/linux/ixp4xx/image/Makefile
@@ -0,0 +1,73 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2006-2021 OpenWrt.org
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+# Cook a Linksys NSLU2 etc image
+define Build/linksys-ixp425-image
+	touch $@.null-initrd
+	$(TOPDIR)/scripts/slugimage.pl -L $(STAGING_DIR_IMAGE)/apex-$(1)-armeb.bin -k $@ -r $@.null-initrd -p -o $@.new
+	mv $@.new $@
+endef
+
+# Build sysupgrade image
+define BuildFirmware/Generic
+	dd if=$(KDIR)/zImage of=$(KDIR)/zImage.pad bs=64k conv=sync; \
+	dd if=$(KDIR)/root.$(1) of=$(KDIR)/root.$(1).pad bs=128k conv=sync; \
+	sh $(TOPDIR)/scripts/combined-image.sh \
+		$(KDIR)/zImage.pad \
+		$(KDIR)/root.$(1).pad \
+		$(BIN_DIR)/$(IMG_PREFIX)-$(patsubst jffs2-%,jffs2,$(patsubst squashfs-%,squashfs,$(1)))-sysupgrade.bin
+endef
+
+define Image/Build
+	$(call Image/Build/$(1),$(1))
+	$(call BuildFirmware/Generic,$(1))
+endef
+
+define Device/Default
+	PROFILES := Default
+	KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
+	KERNEL_NAME := zImage
+	KERNEL := kernel-bin | append-dtb
+	BLOCKSIZE := 128k
+endef
+
+define Device/avila
+	DEVICE_VENDOR := Gateway
+	DEVICE_MODEL := Avila GW2348-4
+	DEVICE_DTS := intel-ixp42x-gateworks-gw2348
+	KERNEL := kernel-bin | append-dtb
+	IMAGES := kernel.bin rootfs.bin
+	IMAGE/kernel.bin := append-kernel
+	IMAGE/rootfs.bin := append-rootfs | pad-rootfs | pad-to 128k
+endef
+TARGET_DEVICES += avila
+
+define Device/cambria
+	DEVICE_VENDOR := Gateway
+	DEVICE_MODEL := Cambria GW2358-4
+	DEVICE_DTS := intel-ixp43x-gateworks-gw2358
+	KERNEL := kernel-bin | append-dtb
+	IMAGES := kernel.bin rootfs.bin
+	IMAGE/kernel.bin := append-kernel
+	IMAGE/rootfs.bin := append-rootfs | pad-rootfs | pad-to 128k
+endef
+TARGET_DEVICES += cambria
+
+define Device/nslu2
+	DEVICE_VENDOR := Linksys
+	DEVICE_MODEL := NSLU2
+	# Only 32 MB of RAM so not building by default
+	DEFAULT := n
+	DEVICE_DTS := intel-ixp42x-linksys-nslu2
+	KERNEL := kernel-bin | append-dtb
+	IMAGES := factory.bin
+	# This has to boot from harddisk so just append the kernel
+	IMAGE/factory.bin := append-kernel | linksys-ixp425-image "nslu2"
+endef
+TARGET_DEVICES += nslu2
+
+$(eval $(call BuildImage))
diff --git a/target/linux/ixp4xx/patches-6.1/0001-mtd-cfi_cmdset_0001-Byte-swap-OTP-info.patch b/target/linux/ixp4xx/patches-6.1/0001-mtd-cfi_cmdset_0001-Byte-swap-OTP-info.patch
new file mode 100644
index 000000000000..1c5e44bb7240
--- /dev/null
+++ b/target/linux/ixp4xx/patches-6.1/0001-mtd-cfi_cmdset_0001-Byte-swap-OTP-info.patch
@@ -0,0 +1,74 @@ 
+From 4e242d6e08ad1d85b832e158cd0eafcb8f3f76a1 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Tue, 30 May 2023 22:40:31 +0200
+Subject: [PATCH v3] mtd: cfi_cmdset_0001: Byte swap OTP info
+
+Currently the offset into the device when looking for OTP
+bits can go outside of the address of the MTD NOR devices,
+and if that memory isn't readable, bad things happen
+on the IXP4xx (added prints that illustrate the problem before
+the crash):
+
+cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x00000100
+ixp4xx_copy_from copy from 0x00000100 to 0xc880dd78
+cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x12000000
+ixp4xx_copy_from copy from 0x12000000 to 0xc880dd78
+8<--- cut here ---
+Unable to handle kernel paging request at virtual address db000000
+[db000000] *pgd=00000000
+(...)
+
+This happens in this case because the IXP4xx is big endian and
+the 32- and 16-bit fields in the struct cfi_intelext_otpinfo are not
+properly byteswapped. Compare to how the code in read_pri_intelext()
+byteswaps the fields in struct cfi_pri_intelext.
+
+Adding a small byte swapping loop for the OTP in read_pri_intelext()
+and the crash goes away.
+
+The problem went unnoticed for many years until I enabled
+CONFIG_MTD_OTP on the IXP4xx as well, triggering the bug.
+
+Cc: Nicolas Pitre <npitre@baylibre.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ChangeLog v2->v3:
+- Move the byte swapping to a small loop in read_pri_intelext()
+  so all bytes are swapped as we reach cfi_intelext_otp_walk().
+ChangeLog v1->v2:
+- Drill deeper and discover a big endian compatibility issue.
+---
+ drivers/mtd/chips/cfi_cmdset_0001.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+--- a/drivers/mtd/chips/cfi_cmdset_0001.c
++++ b/drivers/mtd/chips/cfi_cmdset_0001.c
+@@ -421,9 +421,25 @@ read_pri_intelext(struct map_info *map,
+ 		extra_size = 0;
+ 
+ 		/* Protection Register info */
+-		if (extp->NumProtectionFields)
++		if (extp->NumProtectionFields) {
++			struct cfi_intelext_otpinfo *otp =
++				(struct cfi_intelext_otpinfo *)&extp->extra[0];
++
+ 			extra_size += (extp->NumProtectionFields - 1) *
+-				      sizeof(struct cfi_intelext_otpinfo);
++				sizeof(struct cfi_intelext_otpinfo);
++
++			if (extp_size >= sizeof(*extp) + extra_size) {
++				int i;
++
++				/* Do some byteswapping if necessary */
++				for (i = 0; i < extp->NumProtectionFields - 1; i++) {
++					otp->ProtRegAddr = le32_to_cpu(otp->ProtRegAddr);
++					otp->FactGroups = le16_to_cpu(otp->FactGroups);
++					otp->UserGroups = le16_to_cpu(otp->UserGroups);
++					otp++;
++				}
++			}
++		}
+ 	}
+ 
+ 	if (extp->MinorVersion >= '1') {
diff --git a/target/linux/ixp4xx/patches-6.1/301-ARM-dts-ixp4xx-Boot-NSLU2-from-harddrive.patch b/target/linux/ixp4xx/patches-6.1/301-ARM-dts-ixp4xx-Boot-NSLU2-from-harddrive.patch
new file mode 100644
index 000000000000..ffd69a774c3c
--- /dev/null
+++ b/target/linux/ixp4xx/patches-6.1/301-ARM-dts-ixp4xx-Boot-NSLU2-from-harddrive.patch
@@ -0,0 +1,24 @@ 
+From 2792791a19f90b0141ed2e781599ba0a42a8cfd5 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Mon, 29 May 2023 23:32:44 +0200
+Subject: [PATCH] ARM: dts: ixp4xx: Boot NSLU2 from harddrive
+
+This enforces harddrive boot on the NSLU2. The flash is too small
+to hold any rootfs these days.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts
++++ b/arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts
+@@ -21,7 +21,7 @@
+ 	};
+ 
+ 	chosen {
+-		bootargs = "console=ttyS0,115200n8 root=/dev/mtdblock2 rw rootfstype=squashfs,jffs2 rootwait";
++		bootargs = "console=ttyS0,115200n8 root=/dev/sda1 rw rootwait";
+ 		stdout-path = "uart0:115200n8";
+ 	};
+