commit 273c66b2d3d2b79d3d94afe34d4d41a248b278a6
parent 87f6a31a063f774ce434fd6cbfee12e89b493642
Author: dan <dan@telent.net>
Date: Thu, 8 Feb 2024 17:47:46 +0000
Merge pull request 'Add support for TP-Link Archer AX23' (#6) from raboof/liminix:add-archer-ax23-v1-bak into main
Reviewed-on: https://gti.telent.net/dan/liminix/pulls/6
Diffstat:
6 files changed, 528 insertions(+), 1 deletion(-)
diff --git a/ci.nix b/ci.nix
@@ -11,6 +11,7 @@ let
devices = [
"gl-ar750" "gl-mt300n-v2" "gl-mt300a"
"qemu" "qemu-aarch64" "qemu-armv7l"
+ "tp-archer-ax23"
];
vanilla = ./vanilla-configuration.nix;
for-device = name:
diff --git a/devices/tp-archer-ax23/default.nix b/devices/tp-archer-ax23/default.nix
@@ -0,0 +1,437 @@
+{
+ description = ''
+ TP-Link Archer AX23 / AX1800 Dual Band Wi-Fi 6 Router
+ *****************************************************
+
+ Hardware summary
+ ================
+
+ - MediaTek MT7621 (880MHz)
+ - 16MB Flash
+ - 128MB RAM
+ - WLan hardware: Mediatek MT7905, MT7975
+
+ Limitations
+ ===========
+
+ Status LEDs do not work yet.
+
+ Uploading an image via tftp doesn't work yet, because the Archer uboot
+ version is so old it doesn't support overriding the DTB from the mboot
+ command. The tftpboot module doesn't support this yet, see
+ https://gti.telent.net/dan/liminix/pulls/5 for the WiP.
+ '';
+
+ system = {
+ crossSystem = {
+ config = "mipsel-unknown-linux-musl";
+ gcc = {
+ abi = "32";
+ # https://openwrt.org/docs/techref/instructionset/mipsel_24kc
+ arch = "24kc";
+ };
+ };
+ };
+
+ module = {pkgs, config, lib, lim, ... }:
+ let firmware = pkgs.stdenv.mkDerivation {
+ name = "wlan-firmware";
+ phases = ["installPhase"];
+ installPhase = ''
+ mkdir $out
+ cp ${pkgs.linux-firmware}/lib/firmware/mediatek/{mt7915,mt7615,mt7622}* $out
+ '';
+ };
+ in {
+ imports = [
+ ../../modules/arch/mipsel.nix
+ ../../modules/outputs/tftpboot.nix
+ ../../modules/outputs/tplink-safeloader.nix
+ ];
+ config = {
+ kernel = {
+ src = pkgs.pkgsBuildBuild.fetchurl {
+ name = "linux.tar.gz";
+ url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
+ hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
+ };
+ extraPatchPhase = ''
+ ${pkgs.openwrt.applyPatches.ramips}
+ '';
+ config = {
+ # Initially taken from openwrt's ./target/linux/ramips/mt7621/config-5.15,
+ # then tweaked here and there
+ ARCH_32BIT_OFF_T="y";
+ ARCH_HIBERNATION_POSSIBLE="y";
+ ARCH_KEEP_MEMBLOCK="y";
+ ARCH_MMAP_RND_BITS_MAX="15";
+ ARCH_MMAP_RND_COMPAT_BITS_MAX="15";
+ ARCH_SUSPEND_POSSIBLE="y";
+ AT803X_PHY="y";
+ BLK_MQ_PCI="y";
+ BOARD_SCACHE="y";
+ CEVT_R4K="y";
+ CLKSRC_MIPS_GIC="y";
+ CLK_MT7621="y";
+ CLOCKSOURCE_WATCHDOG="y";
+ CLONE_BACKWARDS="y";
+ CMDLINE_BOOL="y";
+ COMMON_CLK="y";
+ COMPAT_32BIT_TIME="y";
+ CPU_GENERIC_DUMP_TLB="y";
+ CPU_HAS_DIEI="y";
+ CPU_HAS_PREFETCH="y";
+ CPU_HAS_RIXI="y";
+ CPU_HAS_SYNC="y";
+ CPU_LITTLE_ENDIAN="y";
+ CPU_MIPS32="y";
+ CPU_MIPS32_R2="y";
+ CPU_MIPSR2="y";
+ CPU_MIPSR2_IRQ_EI="y";
+ CPU_MIPSR2_IRQ_VI="y";
+ CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS="y";
+ CPU_R4K_CACHE_TLB="y";
+ CPU_RMAP="y";
+ CPU_SUPPORTS_32BIT_KERNEL="y";
+ CPU_SUPPORTS_HIGHMEM="y";
+ CPU_SUPPORTS_MSA="y";
+ CRC16="y";
+ CRYPTO_DEFLATE="y";
+ CRYPTO_HASH_INFO="y";
+ CRYPTO_LIB_BLAKE2S_GENERIC="y";
+ CRYPTO_LIB_POLY1305_RSIZE="2";
+ CRYPTO_LZO="y";
+ CRYPTO_ZSTD="y";
+ CSRC_R4K="y";
+ DIMLIB="y";
+ DMA_NONCOHERENT="y";
+ DTB_RT_NONE="y";
+ DTC="y";
+ EARLY_PRINTK="y";
+ FIXED_PHY="y";
+ FWNODE_MDIO="y";
+ FW_LOADER_PAGED_BUF="y";
+ GENERIC_ATOMIC64="y";
+ GENERIC_CLOCKEVENTS="y";
+ GENERIC_CMOS_UPDATE="y";
+ GENERIC_CPU_AUTOPROBE="y";
+ GENERIC_FIND_FIRST_BIT="y";
+ GENERIC_GETTIMEOFDAY="y";
+ GENERIC_IOMAP="y";
+ GENERIC_IRQ_CHIP="y";
+ GENERIC_IRQ_EFFECTIVE_AFF_MASK="y";
+ GENERIC_IRQ_SHOW="y";
+ GENERIC_LIB_ASHLDI3="y";
+ GENERIC_LIB_ASHRDI3="y";
+ GENERIC_LIB_CMPDI2="y";
+ GENERIC_LIB_LSHRDI3="y";
+ GENERIC_LIB_UCMPDI2="y";
+ GENERIC_PCI_IOMAP="y";
+ GENERIC_PHY="y";
+ GENERIC_PINCONF="y";
+ GENERIC_SCHED_CLOCK="y";
+ GENERIC_SMP_IDLE_THREAD="y";
+ GENERIC_TIME_VSYSCALL="y";
+ GLOB="y";
+ GPIOLIB_IRQCHIP="y";
+ GPIO_CDEV="y";
+ GPIO_GENERIC="y";
+ GPIO_MT7621="y";
+ GRO_CELLS="y";
+ HANDLE_DOMAIN_IRQ="y";
+ HARDWARE_WATCHPOINTS="y";
+ HAS_DMA="y";
+ HAS_IOMEM="y";
+ HAS_IOPORT_MAP="y";
+ I2C="y";
+ I2C_ALGOBIT="y";
+ I2C_BOARDINFO="y";
+ I2C_CHARDEV="y";
+ I2C_GPIO="y";
+ I2C_MT7621="y";
+ ICPLUS_PHY="y";
+ IRQCHIP="y";
+ IRQ_DOMAIN="y";
+ IRQ_DOMAIN_HIERARCHY="y";
+ IRQ_FORCED_THREADING="y";
+ IRQ_MIPS_CPU="y";
+ IRQ_WORK="y";
+ LIBFDT="y";
+ LOCK_DEBUGGING_SUPPORT="y";
+ LZO_COMPRESS="y";
+ LZO_DECOMPRESS="y";
+ MDIO_BUS="y";
+ MDIO_DEVICE="y";
+ MDIO_DEVRES="y";
+ MEDIATEK_GE_PHY="y";
+ MEMFD_CREATE="y";
+ MFD_SYSCON="y";
+ MIGRATION="y";
+ MIKROTIK="y";
+ MIKROTIK_RB_SYSFS="y";
+ MIPS="y";
+ MIPS_ASID_BITS="8";
+ MIPS_ASID_SHIFT="0";
+ MIPS_CLOCK_VSYSCALL="y";
+ MIPS_CM="y";
+ MIPS_CPC="y";
+ MIPS_CPS="y";
+ MIPS_CPU_SCACHE="y";
+ MIPS_GIC="y";
+ MIPS_L1_CACHE_SHIFT="5";
+ MIPS_LD_CAN_LINK_VDSO="y";
+ MIPS_MT="y";
+ MIPS_MT_FPAFF="y";
+ MIPS_MT_SMP="y";
+ MIPS_NR_CPU_NR_MAP="4";
+ MIPS_PERF_SHARED_TC_COUNTERS="y";
+ MIPS_SPRAM="y";
+ MODULES_USE_ELF_REL="y";
+ MTD_CMDLINE_PARTS="y";
+ MTD_NAND_CORE="y";
+ MTD_NAND_ECC="y";
+ MTD_NAND_ECC_SW_HAMMING="y";
+ MTD_NAND_MT7621="y";
+ MTD_NAND_MTK_BMT="y";
+ MTD_RAW_NAND="y";
+ MTD_ROUTERBOOT_PARTS="y";
+ MTD_SERCOMM_PARTS="y";
+ MTD_SPI_NOR="y";
+ MTD_SPLIT_FIT_FW="y";
+ MTD_SPLIT_MINOR_FW="y";
+ MTD_SPLIT_SEAMA_FW="y";
+ MTD_SPLIT_TPLINK_FW="y";
+ MTD_SPLIT_TRX_FW="y";
+ MTD_SPLIT_UIMAGE_FW="y";
+ MTD_UBI="y";
+ MTD_UBI_BEB_LIMIT="20";
+ MTD_UBI_BLOCK="y";
+ MTD_UBI_WL_THRESHOLD="4096";
+ MTD_VIRT_CONCAT="y";
+ NEED_DMA_MAP_STATE="y";
+ NET_DEVLINK="y";
+ NET_DSA="y";
+ NET_DSA_MT7530="y";
+ NET_DSA_MT7530_MDIO="y";
+ NET_DSA_TAG_MTK="y";
+ NET_FLOW_LIMIT="y";
+ NET_MEDIATEK_SOC="y";
+ NET_SELFTESTS="y";
+ NET_SWITCHDEV="y";
+ NET_VENDOR_MEDIATEK="y";
+ NO_HZ_COMMON="y";
+ NO_HZ_IDLE="y";
+ NR_CPUS="4";
+ NVMEM="y";
+ OF="y";
+ OF_ADDRESS="y";
+ OF_EARLY_FLATTREE="y";
+ OF_FLATTREE="y";
+ OF_GPIO="y";
+ OF_IRQ="y";
+ OF_KOBJ="y";
+ OF_MDIO="y";
+ PAGE_POOL="y";
+ PAGE_POOL_STATS="y";
+ PCI="y";
+ PCIE_MT7621="y";
+ PCI_DISABLE_COMMON_QUIRKS="y";
+ PCI_DOMAINS="y";
+ PCI_DOMAINS_GENERIC="y";
+ PCI_DRIVERS_GENERIC="y";
+ PCS_MTK_LYNXI="y";
+ PERF_USE_VMALLOC="y";
+ PGTABLE_LEVELS="2";
+ PHYLIB="y";
+ PHYLINK="y";
+ PHY_MT7621_PCI="y";
+ PINCTRL="y";
+ PINCTRL_AW9523="y";
+ PINCTRL_MT7621="y";
+ PINCTRL_RALINK="y";
+ PINCTRL_SX150X="y";
+ POWER_RESET="y";
+ POWER_RESET_GPIO="y";
+ POWER_SUPPLY="y";
+ PTP_1588_CLOCK_OPTIONAL="y";
+ QUEUED_RWLOCKS="y";
+ QUEUED_SPINLOCKS="y";
+ RALINK="y";
+ RATIONAL="y";
+ REGMAP="y";
+ REGMAP_I2C="y";
+ REGMAP_MMIO="y";
+ REGULATOR="y";
+ REGULATOR_FIXED_VOLTAGE="y";
+ RESET_CONTROLLER="y";
+ RFS_ACCEL="y";
+ RPS="y";
+ RTC_CLASS="y";
+ RTC_DRV_BQ32K="y";
+ RTC_DRV_PCF8563="y";
+ RTC_I2C_AND_SPI="y";
+ SCHED_SMT="y";
+ SERIAL_8250="y";
+ SERIAL_8250_CONSOLE="y";
+ SERIAL_8250_NR_UARTS="3";
+ SERIAL_8250_RUNTIME_UARTS="3";
+ SERIAL_MCTRL_GPIO="y";
+ SERIAL_OF_PLATFORM="y";
+ SGL_ALLOC="y";
+ SMP="y";
+ SMP_UP="y";
+ SOCK_RX_QUEUE_MAPPING="y";
+ SOC_BUS="y";
+ SOC_MT7621="y";
+ SPI="y";
+ SPI_MASTER="y";
+ SPI_MEM="y";
+ SPI_MT7621="y";
+ SRCU="y";
+ SWPHY="y";
+ SYNC_R4K="y";
+ SYSCTL_EXCEPTION_TRACE="y";
+ SYS_HAS_CPU_MIPS32_R1="y";
+ SYS_HAS_CPU_MIPS32_R2="y";
+ SYS_HAS_EARLY_PRINTK="y";
+ SYS_SUPPORTS_32BIT_KERNEL="y";
+ SYS_SUPPORTS_ARBIT_HZ="y";
+ SYS_SUPPORTS_HIGHMEM="y";
+ SYS_SUPPORTS_HOTPLUG_CPU="y";
+ SYS_SUPPORTS_LITTLE_ENDIAN="y";
+ SYS_SUPPORTS_MIPS16="y";
+ SYS_SUPPORTS_MIPS_CPS="y";
+ SYS_SUPPORTS_MULTITHREADING="y";
+ SYS_SUPPORTS_SCHED_SMT="y";
+ SYS_SUPPORTS_SMP="y";
+ SYS_SUPPORTS_ZBOOT="y";
+ TARGET_ISA_REV="2";
+ TICK_CPU_ACCOUNTING="y";
+ TIMER_OF="y";
+ TIMER_PROBE="y";
+ TREE_RCU="y";
+ TREE_SRCU="y";
+ UBIFS_FS="y";
+ USB_SUPPORT="y";
+ USE_OF="y";
+ WEAK_ORDERING="y";
+ XPS="y";
+ XXHASH="y";
+ ZLIB_DEFLATE="y";
+ ZLIB_INFLATE="y";
+ ZSTD_COMPRESS="y";
+ ZSTD_DECOMPRESS="y";
+ } // lib.optionalAttrs (config.system.service ? watchdog) {
+ RALINK_WDT = "y"; # watchdog
+ MT7621_WDT = "y"; # or it might be this one
+ };
+ };
+ tplink-safeloader.board = "ARCHER-AX23-V1";
+ boot = {
+ commandLine = [ "console=ttyS0,115200" ];
+ tftp = {
+ # Should be a segment of free RAM, where the tftp artifact
+ # can be stored before unpacking it to the 'hardware.loadAddress'
+ # The 'hardware.loadAddress' is 0x80001000, which suggests the
+ # RAM would start at 0x8000000 and (being 128MB) go to
+ # to 0x8800000. Let's put it at the 100MB mark at
+ # 0x8000000+0x0640000=0x86400000
+ loadAddress = lim.parseInt "0x86400000";
+ };
+ };
+ filesystem =
+ let inherit (pkgs.pseudofile) dir symlink;
+ in
+ dir {
+ lib = dir {
+ firmware = dir {
+ mediatek = symlink firmware;
+ };
+ };
+ };
+
+ hardware =
+ let
+ openwrt = pkgs.openwrt;
+ mac80211 = pkgs.mac80211.override {
+ drivers = [
+ "mt7915e"
+ ];
+ klibBuild = config.system.outputs.kernel.modulesupport;
+ };
+ in {
+ # from OEM bootlog (openwrt wiki):
+ # 4 cmdlinepart partitions found on MTD device raspi
+ # Creating 4 MTD partitions on "raspi":
+ # 0x000000000000-0x000000040000 : "uboot"
+ # 0x000000040000-0x000000440000 : "uImage"
+ # 0x000000440000-0x000000ff0000 : "rootfs"
+ # 0x000000ff0000-0x000001000000 : "ART"
+ # from openwrt bootlog (openwrt wiki):
+ # 5 fixed-partitions partitions found on MTD device spi0.0
+ # OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
+ # OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
+ # OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
+ # OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
+ # Creating 5 MTD partitions on "spi0.0":
+ # 0x000000000000-0x000000040000 : "u-boot"
+ # 0x000000040000-0x000000fa0000 : "firmware"
+ # 2 uimage-fw partitions found on MTD device firmware
+ # Creating 2 MTD partitions on "firmware":
+ # 0x000000000000-0x0000002c0000 : "kernel"
+ # 0x0000002c0000-0x000000f60000 : "rootfs"
+ # mtd: setting mtd3 (rootfs) as root device
+ # 1 squashfs-split partitions found on MTD device rootfs
+ # 0x000000640000-0x000000f60000 : "rootfs_data"
+ # 0x000000fa0000-0x000000fb0000 : "config"
+ # 0x000000fb0000-0x000000ff0000 : "tplink"
+ # 0x000000ff0000-0x000001000000 : "radio"
+ flash = {
+ # from the OEM bootlog 'Booting image at bc040000'
+ # (0x40000 from 0xbc000000)
+ address = lim.parseInt "0xbc040000";
+ # 0x000000040000-0x000000fa0000
+ size = lim.parseInt "0xf60000";
+ # TODO: find in /proc/mtd on a running system
+ eraseBlockSize = 65536;
+ };
+
+ # since this is mentioned in the partition table as well?
+ defaultOutput = "tplink-safeloader";
+ # taken from openwrt sysupgrade image:
+ # openwrt-23.05.2-ramips-mt7621-tplink_archer-ax23-v1-squashfs-sysupgrade.bin: u-boot legacy uImage, MIPS OpenWrt Linux-5.15.137, Linux/MIPS, OS Kernel Image (lzma), 2797386 bytes, Tue Nov 14 13:38:11 2023, Load Address: 0X80001000, Entry Point: 0X80001000, Header CRC: 0X19F74C5B, Data CRC: 0XF685563C
+ loadAddress = lim.parseInt "0x80001000";
+ entryPoint = lim.parseInt "0x80001000";
+ rootDevice = "/dev/mtdblock3";
+ dts = {
+ src = "${openwrt.src}/target/linux/ramips/dts/mt7621_tplink_archer-ax23-v1.dts";
+ includes = [
+ "${openwrt.src}/target/linux/ramips/dts"
+ "${config.system.outputs.kernel.modulesupport}/arch/arm64/boot/dts/mediatek/"
+ ];
+ };
+
+ networkInterfaces =
+ let
+ inherit (config.system.service.network) link;
+ inherit (config.system.service) bridge;
+ in rec {
+ lan1 = link.build { ifname = "lan1"; };
+ lan2 = link.build { ifname = "lan2"; };
+ lan3 = link.build { ifname = "lan3"; };
+ lan4 = link.build { ifname = "lan4"; };
+ wan = link.build { ifname = "wan"; };
+
+ wlan = link.build {
+ ifname = "wlan0";
+ dependencies = [ mac80211 ];
+ };
+ wlan5 = link.build {
+ ifname = "wlan1";
+ dependencies = [ mac80211 ];
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/modules/outputs.nix b/modules/outputs.nix
@@ -60,6 +60,9 @@ in
Combined kernel and FDT in uImage (U-Boot compatible) format
'';
};
+ tplink-safeloader = mkOption {
+ type = types.package;
+ };
u-boot = mkOption {
type = types.package;
};
diff --git a/modules/outputs/tplink-safeloader.nix b/modules/outputs/tplink-safeloader.nix
@@ -0,0 +1,61 @@
+{
+ config
+, pkgs
+, lib
+, ...
+}:
+let
+ inherit (lib) mkOption types concatStringsSep;
+ o = config.system.outputs;
+ cfg = config.tplink-safeloader;
+in {
+ options.tplink-safeloader = {
+ board = mkOption {
+ type = types.str;
+ };
+ };
+ options.system.outputs = {
+ tplink-safeloader = mkOption {
+ type = types.package;
+ description = ''
+ tplink-safeloader
+ *****************
+
+ For creating 'safeloader' images for tp-link devices.
+
+ These can be flashed to the device using the firmware update feature
+ in the TP-link web UI or the OEM bootloader recovery: Use something
+ sharp to hold the 'reset' button while turning on the router until
+ only the orange LED remains lit. The router will assume IP address
+ 192.168.0.1 and expect you to take 192.168.0.5 on one of the LAN ports.
+ On NixOS, use something like::
+
+ networking.interfaces.enp0s20f0u1c2 = {
+ ipv4.addresses = [ {
+ address = "192.168.0.5";
+ prefixLength = 24;
+ } ];
+ };
+ networking.networkmanager = {
+ unmanaged = [ "enp0s20f0u1c2" ];
+ };
+
+ This connection is rather somewhat temperamental, it may take a couple
+ of attempts, possibly re-attaching the USB dongle and running
+ ``systemctl restart network-start.service``. The web interface does not
+ give accurate feedback (the progress bar is a lie), so you may want
+ to upload the firmware using ``curl -F firmware=@result http://192.168.0.1/f2.htm``.
+ After this shows a 'success' JSON, the image still needs to be
+ transferred from memory to flash, so be patient.
+ '';
+ };
+ };
+ config = {
+ system.outputs = rec {
+ tplink-safeloader =
+ pkgs.runCommand "tplink" { nativeBuildInputs = with pkgs.pkgsBuildBuild; [ firmware-utils ]; } ''
+ tplink-safeloader -B "${cfg.board}" -k "${o.uimage}" -r "${o.rootfs}" -o $out
+ '';
+ };
+ };
+}
diff --git a/pkgs/default.nix b/pkgs/default.nix
@@ -58,7 +58,8 @@ in {
anoia = callPackage ./anoia {};
fennel = callPackage ./fennel {};
fennelrepl = callPackage ./fennelrepl {};
- firewallgen = callPackage ./firewallgen {};
+ firewallgen = callPackage ./firewallgen {};
+ firmware-utils = callPackage ./firmware-utils {};
gen_init_cpio = callPackage ./gen_init_cpio {};
go-l2tp = callPackage ./go-l2tp {};
hi = callPackage ./hi {};
diff --git a/pkgs/firmware-utils/default.nix b/pkgs/firmware-utils/default.nix
@@ -0,0 +1,24 @@
+{ stdenv
+, fetchFromGitHub
+, cmake
+, zlib
+, openssl
+}:
+
+stdenv.mkDerivation {
+ pname = "firmware-utils";
+ version = "snapshot";
+
+ src = fetchFromGitHub {
+ owner = "openwrt";
+ repo = "firmware-utils";
+ rev = "e87f23849790a7c77b4cd0e8ef0384da188174e5";
+ hash = "sha256-285Isf9sRuUt5S56SozgqpnS0+LOfnvpxpnWLwuWYUk=";
+ };
+
+ nativeBuildInputs = [
+ cmake
+ zlib
+ openssl
+ ];
+}