liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

default.nix (15548B)


      1 {
      2   description = ''
      3     == TP-Link Archer AX23 / AX1800 Dual Band Wi-Fi 6 Router
      4 
      5     === Hardware summary
      6 
      7     * MediaTek MT7621 (880MHz)
      8     * 16MB Flash
      9     * 128MB RAM
     10     * WLan hardware: Mediatek MT7905, MT7975
     11 
     12     === Limitations
     13 
     14     Status LEDs do not work yet.
     15 
     16     Uploading an image via tftp doesn't work yet, because the Archer uboot
     17     version is so old it doesn't support overriding the DTB from the mboot
     18     command. The tftpboot module doesn't support this yet, see
     19     https://gti.telent.net/dan/liminix/pulls/5 for the WiP.
     20   '';
     21 
     22   system = {
     23     crossSystem = {
     24       config = "mipsel-unknown-linux-musl";
     25       gcc = {
     26         abi = "32";
     27         # https://openwrt.org/docs/techref/instructionset/mipsel_24kc
     28         arch = "24kc";
     29       };
     30     };
     31   };
     32 
     33   module =
     34     {
     35       pkgs,
     36       config,
     37       lib,
     38       lim,
     39       ...
     40     }:
     41     let
     42       firmware = pkgs.stdenv.mkDerivation {
     43         name = "wlan-firmware";
     44         phases = [ "installPhase" ];
     45         installPhase = ''
     46           mkdir $out
     47           cp ${pkgs.linux-firmware}/lib/firmware/mediatek/{mt7915,mt7615,mt7622}* $out
     48         '';
     49       };
     50     in
     51     {
     52       imports = [
     53         ../../modules/arch/mipsel.nix
     54         ../../modules/outputs/tftpboot.nix
     55         ../../modules/outputs/tplink-safeloader.nix
     56       ];
     57       config = {
     58         kernel = {
     59           extraPatchPhase = ''
     60             ${pkgs.openwrt.applyPatches.ramips}
     61           '';
     62           config = {
     63             # Initially taken from openwrt's ./target/linux/ramips/mt7621/config-5.15,
     64             # then tweaked here and there
     65             ARCH_32BIT_OFF_T = "y";
     66             ARCH_HIBERNATION_POSSIBLE = "y";
     67             ARCH_KEEP_MEMBLOCK = "y";
     68             ARCH_MMAP_RND_BITS_MAX = "15";
     69             ARCH_MMAP_RND_COMPAT_BITS_MAX = "15";
     70             ARCH_SUSPEND_POSSIBLE = "y";
     71             AT803X_PHY = "y";
     72             BLK_MQ_PCI = "y";
     73             BOARD_SCACHE = "y";
     74             CEVT_R4K = "y";
     75             CLKSRC_MIPS_GIC = "y";
     76             CLK_MT7621 = "y";
     77             CLOCKSOURCE_WATCHDOG = "y";
     78             CLONE_BACKWARDS = "y";
     79             CMDLINE_BOOL = "y";
     80             COMMON_CLK = "y";
     81             COMPAT_32BIT_TIME = "y";
     82             CPU_GENERIC_DUMP_TLB = "y";
     83             CPU_HAS_DIEI = "y";
     84             CPU_HAS_PREFETCH = "y";
     85             CPU_HAS_RIXI = "y";
     86             CPU_HAS_SYNC = "y";
     87             CPU_LITTLE_ENDIAN = "y";
     88             CPU_MIPS32 = "y";
     89             CPU_MIPS32_R2 = "y";
     90             CPU_MIPSR2 = "y";
     91             CPU_MIPSR2_IRQ_EI = "y";
     92             CPU_MIPSR2_IRQ_VI = "y";
     93             CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS = "y";
     94             CPU_R4K_CACHE_TLB = "y";
     95             CPU_RMAP = "y";
     96             CPU_SUPPORTS_32BIT_KERNEL = "y";
     97             CPU_SUPPORTS_HIGHMEM = "y";
     98             CPU_SUPPORTS_MSA = "y";
     99             CRC16 = "y";
    100             CRYPTO_DEFLATE = "y";
    101             CRYPTO_HASH_INFO = "y";
    102             CRYPTO_LIB_BLAKE2S_GENERIC = "y";
    103             CRYPTO_LIB_POLY1305_RSIZE = "2";
    104             CRYPTO_LZO = "y";
    105             CRYPTO_ZSTD = "y";
    106             CSRC_R4K = "y";
    107             DIMLIB = "y";
    108             DMA_NONCOHERENT = "y";
    109             DTB_RT_NONE = "y";
    110             DTC = "y";
    111             EARLY_PRINTK = "y";
    112             FIXED_PHY = "y";
    113             FWNODE_MDIO = "y";
    114             FW_LOADER_PAGED_BUF = "y";
    115             GENERIC_ATOMIC64 = "y";
    116             GENERIC_CLOCKEVENTS = "y";
    117             GENERIC_CMOS_UPDATE = "y";
    118             GENERIC_CPU_AUTOPROBE = "y";
    119             GENERIC_FIND_FIRST_BIT = "y";
    120             GENERIC_GETTIMEOFDAY = "y";
    121             GENERIC_IOMAP = "y";
    122             GENERIC_IRQ_CHIP = "y";
    123             GENERIC_IRQ_EFFECTIVE_AFF_MASK = "y";
    124             GENERIC_IRQ_SHOW = "y";
    125             GENERIC_LIB_ASHLDI3 = "y";
    126             GENERIC_LIB_ASHRDI3 = "y";
    127             GENERIC_LIB_CMPDI2 = "y";
    128             GENERIC_LIB_LSHRDI3 = "y";
    129             GENERIC_LIB_UCMPDI2 = "y";
    130             GENERIC_PCI_IOMAP = "y";
    131             GENERIC_PHY = "y";
    132             GENERIC_PINCONF = "y";
    133             GENERIC_SCHED_CLOCK = "y";
    134             GENERIC_SMP_IDLE_THREAD = "y";
    135             GENERIC_TIME_VSYSCALL = "y";
    136             GLOB = "y";
    137             GPIOLIB_IRQCHIP = "y";
    138             GPIO_CDEV = "y";
    139             GPIO_GENERIC = "y";
    140             GPIO_MT7621 = "y";
    141             GRO_CELLS = "y";
    142             HANDLE_DOMAIN_IRQ = "y";
    143             HARDWARE_WATCHPOINTS = "y";
    144             HAS_DMA = "y";
    145             HAS_IOMEM = "y";
    146             HAS_IOPORT_MAP = "y";
    147             I2C = "y";
    148             I2C_ALGOBIT = "y";
    149             I2C_BOARDINFO = "y";
    150             I2C_CHARDEV = "y";
    151             I2C_GPIO = "y";
    152             I2C_MT7621 = "y";
    153             ICPLUS_PHY = "y";
    154             IRQCHIP = "y";
    155             IRQ_DOMAIN = "y";
    156             IRQ_DOMAIN_HIERARCHY = "y";
    157             IRQ_FORCED_THREADING = "y";
    158             IRQ_MIPS_CPU = "y";
    159             IRQ_WORK = "y";
    160             LIBFDT = "y";
    161             LOCK_DEBUGGING_SUPPORT = "y";
    162             LZO_COMPRESS = "y";
    163             LZO_DECOMPRESS = "y";
    164             MDIO_BUS = "y";
    165             MDIO_DEVICE = "y";
    166             MDIO_DEVRES = "y";
    167             MEDIATEK_GE_PHY = "y";
    168             MEMFD_CREATE = "y";
    169             MFD_SYSCON = "y";
    170             MIGRATION = "y";
    171             MIKROTIK = "y";
    172             MIKROTIK_RB_SYSFS = "y";
    173             MIPS = "y";
    174             MIPS_ASID_BITS = "8";
    175             MIPS_ASID_SHIFT = "0";
    176             MIPS_CLOCK_VSYSCALL = "y";
    177             MIPS_CM = "y";
    178             MIPS_CPC = "y";
    179             MIPS_CPS = "y";
    180             MIPS_CPU_SCACHE = "y";
    181             MIPS_GIC = "y";
    182             MIPS_L1_CACHE_SHIFT = "5";
    183             MIPS_LD_CAN_LINK_VDSO = "y";
    184             MIPS_MT = "y";
    185             MIPS_MT_FPAFF = "y";
    186             MIPS_MT_SMP = "y";
    187             MIPS_NR_CPU_NR_MAP = "4";
    188             MIPS_PERF_SHARED_TC_COUNTERS = "y";
    189             MIPS_SPRAM = "y";
    190             MODULES_USE_ELF_REL = "y";
    191             MTD_CMDLINE_PARTS = "y";
    192             MTD_NAND_CORE = "y";
    193             MTD_NAND_ECC = "y";
    194             MTD_NAND_ECC_SW_HAMMING = "y";
    195             MTD_NAND_MT7621 = "y";
    196             MTD_NAND_MTK_BMT = "y";
    197             MTD_RAW_NAND = "y";
    198             MTD_ROUTERBOOT_PARTS = "y";
    199             MTD_SERCOMM_PARTS = "y";
    200             MTD_SPI_NOR = "y";
    201             MTD_SPLIT_FIT_FW = "y";
    202             MTD_SPLIT_MINOR_FW = "y";
    203             MTD_SPLIT_SEAMA_FW = "y";
    204             MTD_SPLIT_TPLINK_FW = "y";
    205             MTD_SPLIT_TRX_FW = "y";
    206             MTD_SPLIT_UIMAGE_FW = "y";
    207             MTD_UBI = "y";
    208             MTD_UBI_BEB_LIMIT = "20";
    209             MTD_UBI_BLOCK = "y";
    210             MTD_UBI_WL_THRESHOLD = "4096";
    211             MTD_VIRT_CONCAT = "y";
    212             NEED_DMA_MAP_STATE = "y";
    213             NET_DEVLINK = "y";
    214             NET_DSA = "y";
    215             NET_DSA_MT7530 = "y";
    216             NET_DSA_MT7530_MDIO = "y";
    217             NET_DSA_TAG_MTK = "y";
    218             NET_FLOW_LIMIT = "y";
    219             NET_MEDIATEK_SOC = "y";
    220             NET_SELFTESTS = "y";
    221             NET_SWITCHDEV = "y";
    222             NET_VENDOR_MEDIATEK = "y";
    223             NO_HZ_COMMON = "y";
    224             NO_HZ_IDLE = "y";
    225             NR_CPUS = "4";
    226             NVMEM = "y";
    227             OF = "y";
    228             OF_ADDRESS = "y";
    229             OF_EARLY_FLATTREE = "y";
    230             OF_FLATTREE = "y";
    231             OF_GPIO = "y";
    232             OF_IRQ = "y";
    233             OF_KOBJ = "y";
    234             OF_MDIO = "y";
    235             PAGE_POOL = "y";
    236             PAGE_POOL_STATS = "y";
    237             PCI = "y";
    238             PCIE_MT7621 = "y";
    239             PCI_DISABLE_COMMON_QUIRKS = "y";
    240             PCI_DOMAINS = "y";
    241             PCI_DOMAINS_GENERIC = "y";
    242             PCI_DRIVERS_GENERIC = "y";
    243             PCS_MTK_LYNXI = "y";
    244             PERF_USE_VMALLOC = "y";
    245             PGTABLE_LEVELS = "2";
    246             PHYLIB = "y";
    247             PHYLINK = "y";
    248             PHY_MT7621_PCI = "y";
    249             PINCTRL = "y";
    250             PINCTRL_AW9523 = "y";
    251             PINCTRL_MT7621 = "y";
    252             PINCTRL_RALINK = "y";
    253             PINCTRL_SX150X = "y";
    254             POWER_RESET = "y";
    255             POWER_RESET_GPIO = "y";
    256             POWER_SUPPLY = "y";
    257             PTP_1588_CLOCK_OPTIONAL = "y";
    258             QUEUED_RWLOCKS = "y";
    259             QUEUED_SPINLOCKS = "y";
    260             RALINK = "y";
    261             RATIONAL = "y";
    262             REGMAP = "y";
    263             REGMAP_I2C = "y";
    264             REGMAP_MMIO = "y";
    265             REGULATOR = "y";
    266             REGULATOR_FIXED_VOLTAGE = "y";
    267             RESET_CONTROLLER = "y";
    268             RFS_ACCEL = "y";
    269             RPS = "y";
    270             RTC_CLASS = "y";
    271             RTC_DRV_BQ32K = "y";
    272             RTC_DRV_PCF8563 = "y";
    273             RTC_I2C_AND_SPI = "y";
    274             SCHED_SMT = "y";
    275             SERIAL_8250 = "y";
    276             SERIAL_8250_CONSOLE = "y";
    277             SERIAL_8250_NR_UARTS = "3";
    278             SERIAL_8250_RUNTIME_UARTS = "3";
    279             SERIAL_MCTRL_GPIO = "y";
    280             SERIAL_OF_PLATFORM = "y";
    281             SGL_ALLOC = "y";
    282             SMP = "y";
    283             SMP_UP = "y";
    284             SOCK_RX_QUEUE_MAPPING = "y";
    285             SOC_BUS = "y";
    286             SOC_MT7621 = "y";
    287             SPI = "y";
    288             SPI_MASTER = "y";
    289             SPI_MEM = "y";
    290             SPI_MT7621 = "y";
    291             SRCU = "y";
    292             SWPHY = "y";
    293             SYNC_R4K = "y";
    294             SYSCTL_EXCEPTION_TRACE = "y";
    295             SYS_HAS_CPU_MIPS32_R1 = "y";
    296             SYS_HAS_CPU_MIPS32_R2 = "y";
    297             SYS_HAS_EARLY_PRINTK = "y";
    298             SYS_SUPPORTS_32BIT_KERNEL = "y";
    299             SYS_SUPPORTS_ARBIT_HZ = "y";
    300             SYS_SUPPORTS_HIGHMEM = "y";
    301             SYS_SUPPORTS_HOTPLUG_CPU = "y";
    302             SYS_SUPPORTS_LITTLE_ENDIAN = "y";
    303             SYS_SUPPORTS_MIPS16 = "y";
    304             SYS_SUPPORTS_MIPS_CPS = "y";
    305             SYS_SUPPORTS_MULTITHREADING = "y";
    306             SYS_SUPPORTS_SCHED_SMT = "y";
    307             SYS_SUPPORTS_SMP = "y";
    308             SYS_SUPPORTS_ZBOOT = "y";
    309             TARGET_ISA_REV = "2";
    310             TICK_CPU_ACCOUNTING = "y";
    311             TIMER_OF = "y";
    312             TIMER_PROBE = "y";
    313             TREE_RCU = "y";
    314             TREE_SRCU = "y";
    315             UBIFS_FS = "y";
    316             USB_SUPPORT = "y";
    317             USE_OF = "y";
    318             WEAK_ORDERING = "y";
    319             XPS = "y";
    320             XXHASH = "y";
    321             ZLIB_DEFLATE = "y";
    322             ZLIB_INFLATE = "y";
    323             ZSTD_COMPRESS = "y";
    324             ZSTD_DECOMPRESS = "y";
    325           }
    326           // lib.optionalAttrs (config.system.service ? watchdog) {
    327             RALINK_WDT = "y"; # watchdog
    328             MT7621_WDT = "y"; # or it might be this one
    329           };
    330           conditionalConfig = {
    331             WLAN = {
    332               MT7915E = "m";
    333             };
    334           };
    335         };
    336         tplink-safeloader.board = "ARCHER-AX23-V1";
    337         boot = {
    338           commandLine = [ "console=ttyS0,115200" ];
    339           tftp = {
    340             # Should be a segment of free RAM, where the tftp artifact
    341             # can be stored before unpacking it to the 'hardware.loadAddress'
    342             # The 'hardware.loadAddress' is 0x80001000, which suggests the
    343             # RAM would start at 0x8000000 and (being 128MB) go to
    344             # to 0x8800000. Let's put it at the 100MB mark at
    345             # 0x8000000+0x0640000=0x86400000
    346             loadAddress = lim.parseInt "0x86400000";
    347           };
    348         };
    349         filesystem =
    350           let
    351             inherit (pkgs.pseudofile) dir symlink;
    352           in
    353           dir {
    354             lib = dir {
    355               firmware = dir {
    356                 mediatek = symlink firmware;
    357               };
    358             };
    359           };
    360 
    361         hardware =
    362           let
    363             openwrt = pkgs.openwrt;
    364             mac80211 = pkgs.kmodloader.override {
    365               targets = [
    366                 "mt7915e"
    367               ];
    368               inherit (config.system.outputs) kernel;
    369             };
    370           in
    371           {
    372             # from OEM bootlog (openwrt wiki):
    373             # 4 cmdlinepart partitions found on MTD device raspi
    374             # Creating 4 MTD partitions on "raspi":
    375             # 0x000000000000-0x000000040000 : "uboot"
    376             # 0x000000040000-0x000000440000 : "uImage"
    377             # 0x000000440000-0x000000ff0000 : "rootfs"
    378             # 0x000000ff0000-0x000001000000 : "ART"
    379             # from openwrt bootlog (openwrt wiki):
    380             # 5 fixed-partitions partitions found on MTD device spi0.0
    381             # OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
    382             # OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
    383             # OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
    384             # OF: Bad cell count for /palmbus@1e000000/spi@b00/flash@0/partitions
    385             # Creating 5 MTD partitions on "spi0.0":
    386             # 0x000000000000-0x000000040000 : "u-boot"
    387             # 0x000000040000-0x000000fa0000 : "firmware"
    388             # 2 uimage-fw partitions found on MTD device firmware
    389             # Creating 2 MTD partitions on "firmware":
    390             # 0x000000000000-0x0000002c0000 : "kernel"
    391             # 0x0000002c0000-0x000000f60000 : "rootfs"
    392             # mtd: setting mtd3 (rootfs) as root device
    393             # 1 squashfs-split partitions found on MTD device rootfs
    394             # 0x000000640000-0x000000f60000 : "rootfs_data"
    395             # 0x000000fa0000-0x000000fb0000 : "config"
    396             # 0x000000fb0000-0x000000ff0000 : "tplink"
    397             # 0x000000ff0000-0x000001000000 : "radio"
    398             flash = {
    399               # from the OEM bootlog 'Booting image at bc040000'
    400               # (0x40000 from 0xbc000000)
    401               address = lim.parseInt "0xbc040000";
    402               # 0x000000040000-0x000000fa0000
    403               size = lim.parseInt "0xf60000";
    404               # TODO: find in /proc/mtd on a running system
    405               eraseBlockSize = 65536;
    406             };
    407 
    408             # since this is mentioned in the partition table as well?
    409             defaultOutput = "tplink-safeloader";
    410             # taken from openwrt sysupgrade image:
    411             # 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
    412             loadAddress = lim.parseInt "0x80001000";
    413             entryPoint = lim.parseInt "0x80001000";
    414             rootDevice = "/dev/mtdblock3";
    415             dts = {
    416               src = "${openwrt.src}/target/linux/ramips/dts/mt7621_tplink_archer-ax23-v1.dts";
    417               includePaths = [
    418                 "${openwrt.src}/target/linux/ramips/dts"
    419                 "${config.system.outputs.kernel.modulesupport}/arch/arm64/boot/dts/mediatek/"
    420               ];
    421             };
    422 
    423             networkInterfaces =
    424               let
    425                 inherit (config.system.service.network) link;
    426               in
    427               rec {
    428                 lan1 = link.build { ifname = "lan1"; };
    429                 lan2 = link.build { ifname = "lan2"; };
    430                 lan3 = link.build { ifname = "lan3"; };
    431                 lan4 = link.build { ifname = "lan4"; };
    432                 wan = link.build { ifname = "wan"; };
    433 
    434                 wlan = link.build {
    435                   ifname = "wlan0";
    436                   dependencies = [ mac80211 ];
    437                 };
    438                 wlan5 = link.build {
    439                   ifname = "wlan1";
    440                   dependencies = [ mac80211 ];
    441                 };
    442               };
    443           };
    444       };
    445     };
    446 }