liminix

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

default.nix (7912B)


      1 {
      2   system = {
      3     crossSystem = {
      4       config = "mips-unknown-linux-musl";
      5       gcc = {
      6         abi = "32";
      7         arch = "24kc"; # maybe mips_24kc-
      8       };
      9     };
     10   };
     11 
     12   description = ''
     13 
     14     == GL.iNet GL-AR750
     15 
     16     === Hardware summary
     17 
     18     The GL-AR750 "Creta" travel router features:
     19 
     20     * QCA9531 @650Mhz SoC
     21     * dual band wireless: IEEE 802.11a/b/g/n/ac
     22     * two 10/100Mbps LAN ports and one WAN
     23     * 128MB DDR2 RAM
     24     * 16MB NOR Flash
     25     * supported in OpenWrt by the "ath79" SoC family
     26 
     27     The GL-AR750 has two distinct sets of wifi hardware. The 2.4GHz radio is
     28     part of the QCA9531 SoC, i.e. it's on the same silicon as the CPU, the
     29     Ethernet, the USB etc. The device is connected to the host via
     30     https://en.wikipedia.org/wiki/Advanced_Microcontroller_Bus_Architecture[AHB]
     31     and it is supported in Linux using the ath9k driver. 5GHz wifi is
     32     provided by a QCA9887 PCIe (PCI embedded) WLAN chip, supported by the
     33     ath10k driver.
     34 
     35     === Installation
     36 
     37     As with many GL.iNet devices, the stock vendor firmware is a fork of
     38     OpenWrt, meaning that the binary created by `+system-outputs-mtdimage+`
     39     can be flashed using the vendor web UI or the U-Boot emergency "unbrick"
     40     routine.
     41 
     42     Flashing over an existing Liminix system is not possible while that
     43     system is running, otherwise you'll be overwriting flash partitions
     44     while they're in use - and that might not end well. Configure the system
     45     with `+levitate+` if you need to make it upgradable.
     46 
     47     Vendor web page: https://www.gl-inet.com/products/gl-ar750/
     48 
     49     OpenWrt web page: https://openwrt.org/toh/gl.inet/gl-ar750
     50 
     51   '';
     52 
     53   module =
     54     {
     55       pkgs,
     56       config,
     57       lim,
     58       lib,
     59       ...
     60     }:
     61     let
     62       inherit (lib) mkIf;
     63       openwrt = pkgs.openwrt_25_12;
     64       firmwareBlobs = pkgs.pkgsBuildBuild.fetchgit {
     65         url = "https://git.codelinaro.org/clo/ath-firmware/ath10k-firmware";
     66         rev = "e1d4991c717ecb252aeabd5f1a3c97551a1906f2";
     67         hash = "sha256-skH12f4ZQouBU6Gb8dgWJYT3kkDFNEq7lg/0RDGJ8LY=";
     68       };
     69       firmware = pkgs.stdenv.mkDerivation {
     70         name = "wlan-firmware";
     71         phases = [ "installPhase" ];
     72         installPhase = ''
     73           mkdir -p $out/ath10k/QCA9887/hw1.0/
     74           blobdir=${firmwareBlobs}/QCA9887/hw1.0
     75           cp $blobdir/10.2.4-1.0/firmware-5.bin_10.2.4-1.0-00047 $out/ath10k/QCA9887/hw1.0/firmware-5.bin
     76           cp $blobdir/board.bin  $out/ath10k/QCA9887/hw1.0/
     77         '';
     78       };
     79       mac80211 = pkgs.kmodloader.override {
     80         targets = [
     81           "ath9k"
     82           "ath10k_pci"
     83         ];
     84         inherit (config.system.outputs) kernel;
     85         dependencies = [ ath10k_cal_data ];
     86       };
     87       ath10k_cal_data =
     88         let
     89           offset = lim.parseInt "0x5000";
     90           size = lim.parseInt "0x844";
     91         in
     92         pkgs.liminix.services.oneshot rec {
     93           name = "ath10k_cal_data";
     94           up = ''
     95             part=$(basename $(dirname $(grep -l art /sys/class/mtd/*/name)))
     96             echo ART partition is ''${part-unset}
     97             test -n "$part" || exit 1
     98             (in_outputs ${name}
     99              dd if=/dev/$part of=data iflag=skip_bytes,fullblock bs=${toString size} skip=${toString offset} count=1
    100             )
    101           '';
    102         };
    103       inherit (pkgs.pseudofile) dir symlink;
    104     in
    105     {
    106       imports = [
    107         ../../modules/network
    108         ../../modules/arch/mipseb.nix
    109         ../../modules/outputs/tftpboot.nix
    110         ../../modules/outputs/mtdimage.nix
    111         ../../modules/outputs/jffs2.nix
    112       ];
    113 
    114       programs.busybox.options = {
    115         FEATURE_DD_IBS_OBS = "y"; # ath10k_cal_data needs skip_bytes,fullblock
    116       };
    117       hardware = {
    118         defaultOutput = "mtdimage";
    119         loadAddress = lim.parseInt "0x80060000";
    120         entryPoint = lim.parseInt "0x80060000";
    121         flash = {
    122           address = lim.parseInt "0x9F060000";
    123           size = lim.parseInt "0xfa0000";
    124           eraseBlockSize = 65536;
    125         };
    126         rootDevice = "/dev/mtdblock5";
    127         dts = {
    128           src = "${openwrt.src}/target/linux/ath79/dts/qca9531_glinet_gl-ar750.dts";
    129           includePaths = [
    130             "${openwrt.src}/target/linux/ath79/dts"
    131           ];
    132           includes = mkIf config.logging.persistent.enable [
    133             ./pstore-ramoops.dtsi
    134           ];
    135         };
    136 
    137         networkInterfaces =
    138           let
    139             inherit (config.system.service.network) link;
    140           in
    141           {
    142             lan = link.build {
    143               ifname = "lan";
    144               devpath = "/devices/platform/ahb/1a000000.eth";
    145             };
    146             wan = link.build {
    147               ifname = "wan";
    148               devpath = "/devices/platform/ahb/19000000.eth";
    149             };
    150             wlan = link.build {
    151               ifname = "wlan0";
    152               dependencies = [ mac80211 ];
    153             };
    154             wlan5 = link.build {
    155               ifname = "wlan1";
    156               dependencies = [
    157                 ath10k_cal_data
    158                 mac80211
    159               ];
    160             };
    161           };
    162       };
    163       filesystem = dir {
    164         lib = dir {
    165           firmware = dir {
    166             ath10k = dir {
    167               QCA9887 = symlink "${firmware}/ath10k/QCA9887";
    168               "cal-pci-0000:00:00.0.bin" = symlink "${ath10k_cal_data}/.outputs/data";
    169             };
    170           };
    171         };
    172       };
    173       boot.tftp = {
    174         loadAddress = lim.parseInt "0x00A00000";
    175         appendDTB = true;
    176       };
    177       kernel = {
    178         # Mainline linux 6.12 doesn't have device-tree support for
    179         # this device or even for the SoC, so we use the extensive
    180         # OpenWrt kernel patches
    181         src = openwrt.kernelSrc;
    182         version = openwrt.kernelVersion;
    183         extraPatchPhase = ''
    184           ${openwrt.applyPatches.ath79}
    185           sed -i.bak -e '\,include <linux/hw_random.h>,a #include <linux/gpio/driver.h>'  drivers/net/wireless/ath/ath9k/ath9k.h # context reqd for next patch
    186         '';
    187 
    188         config = {
    189           ATH79 = "y";
    190           PCI = "y";
    191           PCI_AR724X = "y";
    192 
    193           SERIAL_8250_CONSOLE = "y";
    194           SERIAL_8250 = "y";
    195           SERIAL_CORE_CONSOLE = "y";
    196 
    197           # need this to open console device at boot. dmesg goes from
    198           # [    0.272934] Warning: unable to open an initial console.
    199           # to
    200           # [    0.247413] printk: console [ttyS0] disabled
    201           # [     0.25200] 18020000.uart: ttyS0 at MMIO 0x1802000 (irq = 10, base_baud = 1562500) is a 16550A
    202           SERIAL_OF_PLATFORM = "y";
    203 
    204           CONSOLE_LOGLEVEL_DEFAULT = "8";
    205           CONSOLE_LOGLEVEL_QUIET = "4";
    206 
    207           NET = "y";
    208           ETHERNET = "y";
    209           NET_VENDOR_ATHEROS = "y";
    210           AG71XX_LEGACY = "y"; # ethernet (qca,qca9530-eth)
    211           MFD_SYSCON = "y"; # ethernet (compatible "syscon")
    212           AR8216_PHY = "y"; # eth1 is behind a switch
    213 
    214           MTD_SPI_NOR = "y";
    215 
    216           SPI_ATH79 = "y"; # these are copied from OpenWrt.
    217           SPI_MASTER = "y"; # At least one of them is necessary
    218           SPI_MEM = "y";
    219           SPI_AR934X = "y";
    220           SPI_BITBANG = "y";
    221           SPI_GPIO = "y";
    222 
    223           GPIO_ATH79 = "y";
    224           GPIOLIB = "y";
    225           EXPERT = "y";
    226           GPIO_SYSFS = "y"; # required by patches-5.15/0004-phy-add-ath79-usb-phys.patch
    227           OF_GPIO = "y";
    228           SYSFS = "y";
    229           SPI = "y";
    230           MTD = "y";
    231           MTD_BLOCK = "y"; # fix undefined ref to register_mtd_blktrans_devs
    232 
    233           WATCHDOG = "y";
    234           ATH79_WDT = "y"; # watchdog timer
    235 
    236           EARLY_PRINTK = "y";
    237 
    238           PRINTK_TIME = "y";
    239         };
    240         conditionalConfig = {
    241           WLAN = {
    242             WLAN_VENDOR_ATH = "y";
    243             ATH_COMMON = "m";
    244             ATH9K = "m";
    245             ATH9K_AHB = "y";
    246             ATH10K = "m";
    247             ATH10K_PCI = "m";
    248             ATH10K_DEBUG = "y";
    249           };
    250         };
    251       };
    252     };
    253 }