liminix

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

default.nix (7983B)


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