liminix

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

default.nix (7020B)


      1 
      2 # I like GL.iNet devices because they're relatively accessible to
      3 # DIY users: the serial port connections have headers preinstalled
      4 # and don't need soldering
      5 
      6 # Mainline linux 5.19 doesn't have device-tree support for this device
      7 # or even for the SoC, so we use the extensive OpenWrt kernel patches
      8 
      9 {
     10   system = {
     11     crossSystem = {
     12       config = "mips-unknown-linux-musl";
     13       gcc = {
     14         abi = "32";
     15         arch = "24kc";          # maybe mips_24kc-
     16       };
     17     };
     18   };
     19 
     20   description = ''
     21     GL.INet GL-AR750 "Creta" travel router
     22      - QCA9531 @650Mhz SoC
     23      - dual band wireless: IEEE 802.11a/b/g/n/ac
     24      - two 10/100Mbps LAN ports and one WAN
     25      - 128MB DDR2 RAM / 16MB  NOR Flash
     26      - "ath79" soc family
     27     https://www.gl-inet.com/products/gl-ar750/
     28 
     29     The GL-AR750 has two distinct sets of wifi hardware. The 2.4GHz
     30     radio is part of the QCA9531 SoC, i.e. it's on the same silicon as
     31     the CPU, the Ethernet, the USB etc. The device is connected to the
     32     host via AHB, the "Advanced High-Performance Bus" and it is
     33     supported in Linux using the ath9k driver. The 5GHz support, on the
     34     other hand, is provided by a QCA9887 PCIe (PCI embedded) WLAN chip:
     35     I haven't looked closely at the router innards to see if this is
     36     actually physically a separate board that could be unplugged, but
     37     as far as the Linux is concerned it behaves as one. This is
     38     supported by the ath10k driver.
     39   '';
     40 
     41   module = {pkgs, config, ... }:
     42     let
     43       openwrt = pkgs.openwrt;
     44       firmwareBlobs = pkgs.pkgsBuildBuild.fetchFromGitHub {
     45         owner = "kvalo";
     46         repo = "ath10k-firmware";
     47         rev = "5d63529ffc6e24974bc7c45b28fd1c34573126eb";
     48         sha256 = "1bwpifrwl5mvsmbmc81k8l22hmkwk05v7xs8dxag7fgv2kd6lv2r";
     49       };
     50       firmware = pkgs.stdenv.mkDerivation {
     51         name = "wlan-firmware";
     52         phases = ["installPhase"];
     53         installPhase = ''
     54           mkdir -p $out/ath10k/QCA9887/hw1.0/
     55           blobdir=${firmwareBlobs}/QCA9887/hw1.0
     56           cp $blobdir/10.2.4-1.0/firmware-5.bin_10.2.4-1.0-00047 $out/ath10k/QCA9887/hw1.0/firmware-5.bin
     57           cp $blobdir/board.bin  $out/ath10k/QCA9887/hw1.0/
     58         '';
     59       };
     60       mac80211 = pkgs.mac80211.override {
     61         drivers = ["ath9k" "ath10k_pci"];
     62         klibBuild = config.system.outputs.kernel.modulesupport;
     63       };
     64       ath10k_cal_data =
     65         let
     66           offset = 1024 * 20; # 0x5000
     67           size = 2048 + 68; # 0x844
     68         in pkgs.liminix.services.oneshot rec  {
     69           name = "ath10k_cal_data";
     70           up = ''
     71             part=$(basename $(dirname $(grep -l art /sys/class/mtd/*/name)))
     72             echo ART partition is ''${part-unset}
     73             test -n "$part" || exit 1
     74             (in_outputs ${name}
     75              dd if=/dev/$part of=data iflag=skip_bytes,fullblock bs=${toString size} skip=${toString offset} count=1
     76             )
     77         '';
     78         down = "true";
     79       };
     80       inherit (pkgs.pseudofile) dir symlink;
     81       inherit (pkgs.liminix.networking) interface;
     82     in {
     83       programs.busybox.options = {
     84         FEATURE_DD_IBS_OBS = "y"; # ath10k_cal_data needs skip_bytes,fullblock
     85       };
     86       hardware = {
     87         defaultOutput = "tftpboot";
     88         loadAddress = "0x80060000";
     89         entryPoint  = "0x80060000";
     90         flash = {
     91           address = "0x9F060000";
     92           size ="0xfa0000";
     93           eraseBlockSize = "65536";
     94         };
     95         rootDevice = "/dev/mtdblock5";
     96         dts = {
     97           src = "${openwrt.src}/target/linux/ath79/dts/qca9531_glinet_gl-ar750.dts";
     98           includes =  [
     99             "${openwrt.src}/target/linux/ath79/dts"
    100           ];
    101         };
    102 
    103         networkInterfaces = {
    104           lan = interface { device = "eth0"; };
    105           wan = interface { device = "eth1"; };
    106 
    107           wlan_24 = interface {
    108             device = "wlan0";
    109             dependencies = [ mac80211 ];
    110           };
    111           wlan_5 = interface {
    112             device = "wlan1";
    113             dependencies = [ mac80211 ath10k_cal_data ];
    114           };
    115         };
    116       };
    117       filesystem = dir {
    118         lib = dir {
    119           firmware = dir {
    120             ath10k = dir {
    121               QCA9887 = symlink "${firmware}/ath10k/QCA9887";
    122               "cal-pci-0000:00:00.0.bin" = symlink "${ath10k_cal_data}/.outputs/data";
    123             };
    124           };
    125         };
    126       };
    127       boot.tftp = {
    128         loadAddress = "0x00A00000";
    129       };
    130       kernel = {
    131         src = pkgs.pkgsBuildBuild.fetchurl {
    132           name = "linux.tar.gz";
    133           url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
    134           hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8=";
    135         };
    136         extraPatchPhase = ''
    137           ${openwrt.applyPatches.ath79}
    138         '';
    139         config = {
    140           MIPS_ELF_APPENDED_DTB = "y";
    141           OF = "y";
    142           USE_OF = "y";
    143           ATH79 = "y";
    144           PCI = "y";
    145           PCI_AR724X = "y";
    146 
    147           SERIAL_8250_CONSOLE = "y";
    148           SERIAL_8250 = "y";
    149           SERIAL_CORE_CONSOLE = "y";
    150 
    151           # need this to open console device at boot. dmesg goes from
    152           # [    0.272934] Warning: unable to open an initial console.
    153           # to
    154           # [    0.247413] printk: console [ttyS0] disabled
    155           # [     0.25200] 18020000.uart: ttyS0 at MMIO 0x1802000 (irq = 10, base_baud = 1562500) is a 16550A
    156           SERIAL_OF_PLATFORM = "y";
    157 
    158           CONSOLE_LOGLEVEL_DEFAULT = "8";
    159           CONSOLE_LOGLEVEL_QUIET = "4";
    160 
    161           NET = "y";
    162           NETDEVICES = "y";
    163           ETHERNET = "y";
    164           NET_VENDOR_ATHEROS = "y";
    165           AG71XX = "y";             # ethernet (qca,qca9530-eth)
    166           MFD_SYSCON = "y";         # ethernet (compatible "syscon")
    167           AR8216_PHY = "y";         # eth1 is behind a switch
    168 
    169           MTD_SPI_NOR = "y";
    170           MTD_SPI_NOR_USE_4K_SECTORS = "n";  # jffs2 needs min 8k erase block
    171 
    172           SPI_ATH79 = "y";      # these are copied from OpenWrt.
    173           SPI_MASTER= "y";      # At least one of them is necessary
    174           SPI_MEM= "y";
    175           SPI_AR934X= "y";
    176           SPI_BITBANG= "y";
    177           SPI_GPIO= "y";
    178 
    179           GPIO_ATH79 = "y";
    180           GPIOLIB = "y";
    181           EXPERT="y";
    182           GPIO_SYSFS = "y"; # required by patches-5.15/0004-phy-add-ath79-usb-phys.patch
    183           OF_GPIO = "y";
    184           SYSFS = "y";
    185           SPI = "y";
    186           MTD = "y";
    187           MTD_CMDLINE_PARTS = "y";
    188           MTD_BLOCK = "y";          # fix undefined ref to register_mtd_blktrans_devs
    189 
    190           WATCHDOG = "y";
    191           ATH79_WDT = "y";  # watchdog timer
    192 
    193           CPU_BIG_ENDIAN= "y";
    194 
    195           # this is all copied from nixwrt ath79 config. Clearly not all
    196           # of it is device config, some of it is wifi config or
    197           # installation method config or ...
    198 
    199           CMDLINE_PARTITION = "y";
    200           EARLY_PRINTK = "y";
    201 
    202           PARTITION_ADVANCED = "y";
    203           PRINTK_TIME = "y";
    204           SQUASHFS = "y";
    205           SQUASHFS_XZ = "y";
    206         };
    207       };
    208     };
    209 }